CORD-1157: Bug fixes to xproto generator + Added Makefile to integrate
with corebuilder

Change-Id: Ic76d02d0d4cb04255f17e68734c738cd3c8204fc
diff --git a/xos/genx/protos/core/loadablemodule.proto b/xos/genx/protos/core/loadablemodule.proto
index 892035f..0fd55f3 100644
--- a/xos/genx/protos/core/loadablemodule.proto
+++ b/xos/genx/protos/core/loadablemodule.proto
@@ -1,4 +1,3 @@
-
 message LoadableModule {
   required int32 xos = 1 [ null = False,  default = "get_xos()",  blank = False,  help_text = "Pointer to XOS",  model = XOS,  modifier = required,  type = link,  port = loadable_modules,  db_index = True ];
   required string name = 2 [ null = False,  max_length = 30,  content_type = "stripped",  blank = False,  help_text = "Service Name",  modifier = required,  db_index = False ];
@@ -6,4 +5,4 @@
   optional string version = 4 [ null = True,  default = "1.0.0",  max_length = 30,  content_type = "stripped",  blank = True,  help_text = "Version of Service Controller",  modifier = optional,  db_index = False ];
   optional string provides = 5 [ null = True,  max_length = 254,  content_type = "stripped",  blank = True,  help_text = "Comma-separated list of things provided",  modifier = optional,  db_index = False ];
   optional string requires = 6 [ null = True,  max_length = 254,  content_type = "stripped",  blank = True,  help_text = "Comma-separated list of required Service Controllers",  modifier = optional,  db_index = False ];
-}
\ No newline at end of file
+}
diff --git a/xos/genx/targets/django-split.xtarget b/xos/genx/targets/django-split.xtarget
index 6f43e3b..f3a998b 100644
--- a/xos/genx/targets/django-split.xtarget
+++ b/xos/genx/targets/django-split.xtarget
@@ -28,7 +28,7 @@
 
   # Relations
   {% for l in m.links %}
-  {{ l.src_port }} = {{ xproto_django_link_type(l) }}( {%- if l.peer==m.name -%}'self'{%- else -%}{{ l.peer }} {%- endif -%}, {{ xproto_django_options_str(l, l.dst_port ) }} )
+  {{ l.src_port }} = {{ xproto_django_link_type(l) }}( {%- if l.peer==m.name -%}'self'{%- else -%}{{ l.peer }} {%- endif -%}, {{ xproto_django_link_options_str(l, l.dst_port ) }} )
   {%- endfor %}
 
   {% if file_exists(m.name|lower + '_model.py') -%}{{ include_file(m.name|lower + '_model.py') | indent(width=2)}}{%- endif %}
diff --git a/xos/genx/targets/django.xtarget b/xos/genx/targets/django.xtarget
index 66948ff..131676a 100644
--- a/xos/genx/targets/django.xtarget
+++ b/xos/genx/targets/django.xtarget
@@ -1,14 +1,18 @@
 
 from header import *
 {% for m in proto.messages %}
-{% if file_exists(xproto_base_name(m.name)+'_header.py'|lower) -%}from {{m.name|lower}}_header import *{% endif %}
-{% if file_exists(xproto_base_name(m.name)+'_top.py'|lower) -%}{{ include_file(xproto_base_name(m.name)|lower+'_top.py') }}{% endif %}
+{% if file_exists(xproto_base_name(m.name)|lower+'_header.py') -%}from {{xproto_base_name(m.name)|lower }}_header import *{% endif %}
+{% if file_exists(xproto_base_name(m.name)|lower+'_top.py') -%}{{ include_file(xproto_base_name(m.name)|lower+'_top.py') }} {% endif %}
 
 {%- for l in m.links %}
+
+{% if l.peer != m.name %}
 from core.models.{{ l.peer | lower }} import {{ l.peer }} 
+{% endif %}
+
 {%- endfor %}
 {% for b in m.bases %}
-{% if b!='PlCoreBase' and b!='AttributeMixin'%}
+{% if b!='PlCoreBase' and 'Mixin' not in b%}
 from core.models.{{b | lower}} import {{ b }}
 {% endif %}
 {% endfor %}
@@ -24,11 +28,11 @@
 
   # Relations
   {% for l in m.links %}
-  {{ l.src_port }} = {{ xproto_django_link_type(l) }}( {{ l.peer }}, {{ xproto_django_options_str(l, l.dst_port ) }} )
+  {{ l.src_port }} = {{ xproto_django_link_type(l) }}( {%- if l.peer==m.name -%}'self'{%- else -%}{{ l.peer }} {%- endif -%}, {{ xproto_django_link_options_str(l, l.dst_port ) }} )
   {%- endfor %}
 
   {% if file_exists(m.name|lower + '_model.py') -%}{{ include_file(m.name|lower + '_model.py') | indent(width=2)}}{%- endif %}
+  pass
 
 {% if file_exists(xproto_base_name(m.name)|lower+'_bottom.py') -%}{{ include_file(xproto_base_name(m.name)|lower+'_bottom.py') }}{% endif %}
-+++ models/{{m.name|lower}}.py
 {% endfor %}
diff --git a/xos/genx/targets/init.xtarget b/xos/genx/targets/init.xtarget
new file mode 100644
index 0000000..df0abdf
--- /dev/null
+++ b/xos/genx/targets/init.xtarget
@@ -0,0 +1,15 @@
+# The hardcoded entries cannot be inferred from the models. To get rid of in the long run
+# 
+
+from .plcorebase import PlCoreBase,PlCoreBaseManager,PlCoreBaseDeletionManager,PlModelMixIn,ModelLink
+from .singletonmodel import SingletonModel
+from .site import Site
+from .dashboardview import DashboardView
+from .user import User
+from .user import UserDashboardView
+from .header import ControllerManager, ControllerDeletionManager, ControllerLinkManager,ControllerLinkDeletionManager
+from .journal import JournalEntry, journal_object
+
+{% for m in proto.messages -%}
+from .{{ m.name | lower }} import {{ m.name }} 
+{% endfor -%}
diff --git a/xos/genx/tool/Makefile b/xos/genx/tool/Makefile
new file mode 100644
index 0000000..a4dfcae
--- /dev/null
+++ b/xos/genx/tool/Makefile
@@ -0,0 +1,25 @@
+# Replace the line below with the location of xosgen
+PREFIX=.
+XOSGEN=$(PREFIX)/tool/xosgen
+
+DJANGO_TARGET=$(PREFIX)/targets/django-split.xtarget
+INIT_TARGET=$(PREFIX)/targets/init.xtarget
+XPROTOS_TMP := $(shell mktemp)
+
+%.py: %.xproto
+	$(XOSGEN) --attic attic --input $< --target $(DJANGO_TARGET) --output $@ 
+
+xprotos = $(wildcard *.xproto)
+pys = $(xprotos:.xproto=.py)
+
+all: $(pys) __init__.py
+
+__init__.py: $(xprotos)
+	cat $(xprotos) > $(XPROTOS_TMP)
+	$(XOSGEN) --attic attic --input $(XPROTOS_TMP) --target $(INIT_TARGET) --output $@ | awk '!seen[$$0]++' > __init__.py
+
+.PHONY: clean all init
+	
+clean:
+	rm -f $(pys) 
+	rm -f __init__.py
diff --git a/xos/genx/tool/lib.py b/xos/genx/tool/lib.py
index 0121bd6..9f6c3a9 100644
--- a/xos/genx/tool/lib.py
+++ b/xos/genx/tool/lib.py
@@ -1,9 +1,6 @@
 import pdb
 import re
 
-def xproto_eval(arg):
-    return eval(arg)
-
 def django_content_type_string(xptags):
     # Check possibility of KeyError in caller
     content_type = xptags['content_type']
@@ -121,9 +118,10 @@
         output_dict['related_name'] = '%r'%dport
 
     try:
-        if field['through'] and not field['through'].endswith('_'+field.name):
-            output_dict['through'] = field['through']
-    except:
+        if field['through']:
+            if not field['through'].endswith('_'+field['name']):
+                output_dict['through'] = '%r'%field['through']
+    except KeyError:
         pass
 
     return format_options_string(output_dict)
diff --git a/xos/genx/tool/xosgen b/xos/genx/tool/xosgen
index bfecfbe..59934a7 100755
--- a/xos/genx/tool/xosgen
+++ b/xos/genx/tool/xosgen
@@ -18,14 +18,16 @@
 parse.add_argument('--input', dest='input', action='store',default=None, help='Filename in Protobufs')
 parse.add_argument('--target', dest='target', action='store',default=None, help='Output format, corresponding to <output>.yaml file')
 parse.add_argument('--output', dest='output', action='store',default=None, help='Destination path')
+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')
 
 args = parse.parse_args()
 
 def file_exists(name):
-    return (os.path.exists('attic/'+name))
+    return (os.path.exists(args.attic+'/'+name))
 
 def include_file(name):
-    return open('attic/'+name).read()
+    return open(args.attic+'/'+name).read()
     # FIXME: Support templates in the future
     #return jinja2.Markup(loader.get_source(env, name)[0])
 
@@ -57,18 +59,29 @@
                 os_template_env.globals[f] = getattr(lib, f)
 
         template = os_template_env.get_template(os.path.split(template_name)[1])
-        rendered = template.render({"proto": {'messages':v.messages}})
+        context = {}
+
+        try:
+            for s in args.kv.split(','):
+                k,val=s.split(':')
+                context[k]=val
+        except:
+            pass
+
+        rendered = template.render({"proto": {'messages':v.messages},"context":context})
 
         lines = rendered.splitlines()
         current_buffer = []
         for l in lines:
             if (l.startswith('+++')):
-                prefix = args.output.rsplit('/',1)[0]
-                path = prefix+'/'+l[4:]
+                prefixes = args.output.rsplit('/',1)
+                if (len(prefixes)>1):
+                    path = prefix+'/'+l[4:]
+                    direc = prefix
+                    os.system('mkdir -p %s'%direc)
+                else:
+                    path = l[4:]
                 
-                direc,filename = path.rsplit('/',1)
-                os.system('mkdir -p %s'%direc)
-              
                 fil = open(path,'w')
                 buf = '\n'.join(current_buffer)
 
diff --git a/xos/genx/xprotos/core/project.xproto b/xos/genx/xprotos/core/project.xproto
index d857de9..b7ea398 100644
--- a/xos/genx/xprotos/core/project.xproto
+++ b/xos/genx/xprotos/core/project.xproto
@@ -1,5 +1,4 @@
 
-
 message Project (PlCoreBase){
      required string name = 1 [max_length = 200, content_type = "stripped", blank = False, help_text = "Name of Project", null = False, db_index = False];
 }