-
-def generate_facacdes(options):
- global classes
- schemas = json.loads(Path(options.schema).read_text("utf-8"))
- capture = codegen.CodeWriter()
- capture.write("""
-from juju.client.facade import Type, ReturnMapping
- """)
- schemas = [Schema(s) for s in schemas]
-
- for schema in schemas:
- schema.buildDefinitions()
- buildTypes(schema, capture)
-
- for schema in schemas:
- # TODO generate class now with a metaclass that takes the schema
- # the generated class has the right name and it in turn uses
- # the metaclass to populate cls
- cls, source = buildFacade(schema)
- capture.write(source)
- buildMethods(cls, capture)
- classes[schema.name] = cls
-
- return capture
+def make_factory(name):
+ if name in factories:
+ del factories[name]
+ factories[name].write("class {}(TypeFactory):\n pass\n\n".format(name))
+
+
+def write_facades(captures, options):
+ """
+ Write the Facades to the appropriate _client<version>.py
+
+ """
+ for version in sorted(captures.keys()):
+ filename = "{}/_client{}.py".format(options.output_dir, version)
+ with open(filename, "w") as f:
+ f.write(HEADER)
+ f.write("from juju.client.facade import Type, ReturnMapping\n")
+ f.write("from juju.client._definitions import *\n\n")
+ for key in sorted(
+ [k for k in captures[version].keys() if "Facade" in k]):
+ print(captures[version][key], file=f)
+
+ # Return the last (most recent) version for use in other routines.
+ return version
+
+
+def write_definitions(captures, options, version):
+ """
+ Write auxillary (non versioned) classes to
+ _definitions.py The auxillary classes currently get
+ written redudantly into each capture object, so we can look in
+ one of them -- we just use the last one from the loop above.
+
+ """
+ with open("{}/_definitions.py".format(options.output_dir), "w") as f:
+ f.write(HEADER)
+ f.write("from juju.client.facade import Type, ReturnMapping\n\n")
+ for key in sorted(
+ [k for k in captures[version].keys() if "Facade" not in k]):
+ print(captures[version][key], file=f)
+
+
+def write_client(captures, options):
+ """
+ Write the TypeFactory classes to _client.py, along with some
+ imports and tables so that we can look up versioned Facades.
+
+ """
+ with open("{}/_client.py".format(options.output_dir), "w") as f:
+ f.write(HEADER)
+ f.write("from juju.client._definitions import *\n\n")
+ clients = ", ".join("_client{}".format(v) for v in captures)
+ f.write("from juju.client import " + clients + "\n\n")
+ f.write(CLIENT_TABLE.format(clients=",\n ".join(
+ ['"{}": _client{}'.format(v, v) for v in captures])))
+ f.write(LOOKUP_FACADE)
+ f.write(TYPE_FACTORY)
+ for key in sorted([k for k in factories.keys() if "Facade" in k]):
+ print(factories[key], file=f)
+
+
+def generate_facades(options):
+ captures = defaultdict(codegen.Capture)
+ schemas = {}
+ for p in sorted(glob(options.schema)):
+ if 'latest' in p:
+ juju_version = 'latest'
+ else:
+ try:
+ juju_version = re.search(JUJU_VERSION, p).group()
+ except AttributeError:
+ print("Cannot extract a juju version from {}".format(p))
+ print("Schemas must include a juju version in the filename")
+ raise SystemExit(1)
+
+ new_schemas = json.loads(Path(p).read_text("utf-8"))
+ schemas[juju_version] = [Schema(s) for s in new_schemas]
+
+ # Build all of the auxillary (unversioned) classes
+ # TODO: get rid of some of the excess trips through loops in the
+ # called functions.
+ for juju_version in sorted(schemas.keys()):
+ for schema in schemas[juju_version]:
+ schema.buildDefinitions()
+ buildTypes(schema, captures[schema.version])
+
+ # Build the Facade classes
+ for juju_version in sorted(schemas.keys()):
+ for schema in schemas[juju_version]:
+ cls, source = buildFacade(schema)
+ cls_name = "{}Facade".format(schema.name)
+
+ captures[schema.version].clear(cls_name)
+ # Make the factory class for _client.py
+ make_factory(cls_name)
+ # Make the actual class
+ captures[schema.version][cls_name].write(source)
+ # Build the methods for each Facade class.
+ buildMethods(cls, captures[schema.version])
+ # Mark this Facade class as being done for this version --
+ # helps mitigate some excessive looping.
+ CLASSES[schema.name] = cls
+
+ return captures