SEBA-282 xosgenx filtering by app or model;
provide a default argument class for XOSProcessor;
remove tabs;
rename unit tests missed by nose2
Change-Id: I07b782982b6733f8828b8a5a72807326f430b1a5
diff --git a/lib/xos-genx/xosgenx/generator.py b/lib/xos-genx/xosgenx/generator.py
index dc1ff9e..3355fb5 100644
--- a/lib/xos-genx/xosgenx/generator.py
+++ b/lib/xos-genx/xosgenx/generator.py
@@ -26,6 +26,43 @@
loader = jinja2.PackageLoader(__name__, 'templates')
env = jinja2.Environment(loader=loader)
+class XOSProcessorArgs:
+ """ Helper class for use cases that want to call XOSProcessor directly, rather than executing xosgenx from the
+ command line.
+ """
+
+ default_rev = False
+ default_output = None
+ default_attic = None
+ default_kvpairs = None
+ default_write_to_file = None
+ default_dest_file = None
+ default_dest_extension = None
+ default_target = None
+ default_checkers = None
+ default_verbosity = 0 # Higher numbers = more verbosity, lower numbers = less verbosity
+ default_include_models = [] # If neither include_models nor include_apps is specified, then all models will
+ default_include_apps = [] # be included.
+
+ def __init__(self, **kwargs):
+ # set defaults
+ self.rev = XOSProcessorArgs.default_rev
+ self.output = XOSProcessorArgs.default_output
+ self.attic = XOSProcessorArgs.default_attic
+ self.kvpairs = XOSProcessorArgs.default_kvpairs
+ self.verbosity = XOSProcessorArgs.default_verbosity
+ self.write_to_file = XOSProcessorArgs.default_write_to_file
+ self.default_dest_file = XOSProcessorArgs.default_dest_file
+ self.default_dest_extension = XOSProcessorArgs.default_dest_extension
+ self.default_target = XOSProcessorArgs.default_target
+ self.default_checkers = XOSProcessorArgs.default_target
+ self.include_models = XOSProcessorArgs.default_include_models
+ self.include_apps = XOSProcessorArgs.default_include_apps
+
+ # override defaults with kwargs
+ for (k,v) in kwargs.items():
+ setattr(self, k, v)
+
class XOSProcessor:
@staticmethod
@@ -225,7 +262,7 @@
if start == 0:
beginning = ''
else:
- beginning = inputs[ptr:start-1]
+ beginning = inputs[ptr:start-1]
line_end_char = inputs[start+end:].find('\n')
line_end = inputs[line_end_char]
@@ -242,6 +279,19 @@
v = XOSProcessor._attach_parser(ast, args)
+ if args.include_models or args.include_apps:
+ for message in v.messages:
+ message["is_included"] = False
+ if message["name"] in args.include_models:
+ message["is_included"] = True
+ else:
+ app_label = message.get("options", {}).get("app_label").strip('"')
+ if app_label in args.include_apps:
+ message["is_included"] = True
+ else:
+ for message in v.messages:
+ message["is_included"] = True
+
if args.output is not None and args.write_to_file == "model":
rendered = {}
for i, model in enumerate(v.models):
@@ -255,7 +305,7 @@
'message_table': models,
'messages': messages,
'policies': v.policies,
- 'message_names': [m['name'] for m in messages]
+ 'message_names': [m['name'] for m in v.messages]
},
"context": context,
"options": v.options
diff --git a/lib/xos-genx/xosgenx/jinja2_extensions/base.py b/lib/xos-genx/xosgenx/jinja2_extensions/base.py
index 3bfcd70..af1c241 100644
--- a/lib/xos-genx/xosgenx/jinja2_extensions/base.py
+++ b/lib/xos-genx/xosgenx/jinja2_extensions/base.py
@@ -164,6 +164,9 @@
# The "id" field is a special field. Every model has one. Put it up front and pretend it's part of the
+ if not fields:
+ raise Exception("Model %s has no fields. Check for missing base class." % m["name"])
+
id_field = {'type': 'int32', 'name': 'id', 'options': {}, "id": "1", "accessor": fields[0]["accessor"]}
fields = [id_field] + fields
diff --git a/lib/xos-genx/xosgenx/targets/protoapi.xtarget b/lib/xos-genx/xosgenx/targets/protoapi.xtarget
index 2311b98..e87e7d8 100644
--- a/lib/xos-genx/xosgenx/targets/protoapi.xtarget
+++ b/lib/xos-genx/xosgenx/targets/protoapi.xtarget
@@ -11,7 +11,7 @@
// fields that are set by the caller, regardless if they are set to a default
// value. XOS uses this to know when to apply a default value.
-{% for object in proto.messages|sort(attribute='name') %}
+{% for object in proto.messages|selectattr("is_included")|sort(attribute='name') %}
{% if object.name != 'XOSBase' -%}
message {{ object.name }} {
{%- if object.name=='CordSubscriberRoot' %}
@@ -47,7 +47,7 @@
{% endfor %}
service xos {
-{% for object in proto.messages | sort(attribute='name')%}
+{% for object in proto.messages | selectattr("is_included") | sort(attribute='name')%}
{% if object.name != 'XOSBase' -%}
rpc List{{ object.name }}(google.protobuf.Empty) returns ({{ xproto_pluralize(object) }}) {
option (googleapi.http) = {
diff --git a/lib/xos-genx/xosgenx/xosgen.py b/lib/xos-genx/xosgenx/xosgen.py
index 8259d58..27a7fb4 100755
--- a/lib/xos-genx/xosgenx/xosgen.py
+++ b/lib/xos-genx/xosgenx/xosgen.py
@@ -21,21 +21,36 @@
from version import __version__
parse = argparse.ArgumentParser(description='XOS Generative Toolchain')
-parse.add_argument('--rev', dest='rev', action='store_true',default=False, help='Convert proto to xproto')
-parse.add_argument('--output', dest='output', action='store',default=None, help='Destination dir')
-parse.add_argument('--attic', dest='attic', action='store',default=None, help='The location at which static files are stored')
-parse.add_argument('--kvpairs', dest='kv', action='store',default=None, help='Key value pairs to make available to the target')
-parse.add_argument('--write-to-file', dest='write_to_file', choices = ['single', 'model', 'target'], action='store',default=None, help='Single output file (single) or output file per model (model) or let target decide (target)')
+parse.add_argument('--rev', dest='rev', action='store_true',
+ default=XOSProcessorArgs.default_rev, help='Convert proto to xproto')
+parse.add_argument('--output', dest='output', action='store',
+ default=XOSProcessorArgs.default_output, help='Destination dir')
+parse.add_argument('--attic', dest='attic', action='store',
+ default=XOSProcessorArgs.default_attic, help='The location at which static files are stored')
+parse.add_argument('--kvpairs', dest='kv', action='store',
+ default=XOSProcessorArgs.default_kvpairs, help='Key value pairs to make available to the target')
+parse.add_argument('--write-to-file', dest='write_to_file', choices = ['single', 'model', 'target'], action='store',
+ default=XOSProcessorArgs.default_write_to_file,
+ help='Single output file (single) or output file per model (model) or let target decide (target)')
parse.add_argument('--version', action='version', version=__version__)
-parse.add_argument("-v", "--verbosity", action="count", default=0, help="increase output verbosity")
+parse.add_argument("-v", "--verbosity", action="count",
+ default=XOSProcessorArgs.default_verbosity, help="increase output verbosity")
+parse.add_argument("--include-models", dest="include_models", action="append",
+ default=XOSProcessorArgs.default_include_models, help="list of models to include")
+parse.add_argument("--include-apps", dest="include_apps", action="append",
+ default=XOSProcessorArgs.default_include_apps, help="list of models to include")
group = parse.add_mutually_exclusive_group()
-group.add_argument('--dest-file', dest='dest_file', action='store',default=None, help='Output file name (if write-to-file is set to single)')
-group.add_argument('--dest-extension', dest='dest_extension', action='store',default=None, help='Output file extension (if write-to-file is set to single)')
+group.add_argument('--dest-file', dest='dest_file', action='store',
+ default=XOSProcessorArgs.default_dest_file, help='Output file name (if write-to-file is set to single)')
+group.add_argument('--dest-extension', dest='dest_extension', action='store',
+ default=XOSProcessorArgs.default_dest_extension, help='Output file extension (if write-to-file is set to single)')
group = parse.add_mutually_exclusive_group(required=True)
-group.add_argument('--target', dest='target', action='store',default=None, help='Output format, corresponding to <output>.yaml file')
-group.add_argument('--checkers', dest='checkers', action='store', default=None, help='Comma-separated list of static checkers')
+group.add_argument('--target', dest='target', action='store',
+ default=XOSProcessorArgs.default_target, help='Output format, corresponding to <output>.yaml file')
+group.add_argument('--checkers', dest='checkers', action='store',
+ default=XOSProcessorArgs.default_checkers, help='Comma-separated list of static checkers')
parse.add_argument('files', metavar='<input file>', nargs='+', action='store', help='xproto files to compile')