-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP: Added docgen command #60
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
# (c) Copyright 2017-2018 OLX | ||
|
||
from __future__ import absolute_import | ||
from __future__ import division | ||
from __future__ import print_function | ||
from __future__ import unicode_literals | ||
|
||
from command import Command | ||
from .bases import CommandRepositoryBase | ||
import load_python | ||
import os | ||
|
||
class Command_docgen(Command, CommandRepositoryBase): | ||
""" | ||
Generate the documentation of all classes supported by rubiks on your local rubiks folder. | ||
""" | ||
|
||
_documentation = """ | ||
This document is automatically generated using the command `docgen` and describe all the object and types that can be used inside Rubiks to configure your cluster | ||
|
||
It is possible to generate this documentation locally running inside your rubiks repo `rubiks docgen`. | ||
""" | ||
|
||
def populate_args(self, parser): | ||
pass | ||
|
||
def run(self, args): | ||
self.get_repository(can_fail=True) | ||
objs = load_python.PythonBaseFile.get_kube_objs() | ||
types = load_python.PythonBaseFile.get_kube_types() | ||
formats = load_python.PythonBaseFile.get_kube_vartypes() | ||
|
||
r = self.get_repository() | ||
|
||
doc = '\n'.join([line.strip() for line in self._documentation.split('\n')]) | ||
|
||
md = '' | ||
header = '<p align="center"><img src="logos/rubiks-logo-horizontal.png" title="Rubiks Logo"></p>\n\n' | ||
header += '# Rubiks Object Index\n{}\n\n'.format(doc) | ||
header += '# Table of contents\n\n' | ||
|
||
header += '- [Formats](#formats)\n' | ||
md += '\n# Formats\n\n' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This structure makes sense if you add options (which I think you should) for which sections you should generate. And as mentioned, I think "formats" is an awful name for this. |
||
for fname in sorted(formats.keys()): | ||
header += ' - [{}](#{})\n'.format(fname, fname.lower()) | ||
md += '## {}\n\n'.format(fname) | ||
md += '{}\n\n'.format(formats[fname].get_description()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. particularly because of this! |
||
|
||
header += '- [Types](#types)\n' | ||
md += '\n# Types\n\n' | ||
for tname in sorted(types.keys()): | ||
header += ' - [{}](#{})\n'.format(tname, tname.lower()) | ||
md += '## {}\n\n'.format(tname) | ||
md += '{}\n\n'.format(types[tname].get_description()) | ||
|
||
|
||
header += '- [Objects](#objects)\n' | ||
md += '\n# Objects\n\n' | ||
for oname in sorted(objs.keys()): | ||
header += ' - [{}](#{})\n'.format(oname, oname.lower()) | ||
md += objs[oname].get_help().render_markdown() | ||
|
||
with open(os.path.join(r.basepath, 'docs/rubiks.class.md'), 'w') as f: | ||
f.write(header.encode('utf-8')) | ||
f.write(md.encode('utf-8')) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again, please fix your editor so that the file ends in a newline and we don't get spurious diffs down the line. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -61,6 +61,12 @@ def construct_arg(cls, arg): | |
ret = Object(ret.__class__) | ||
|
||
return ret | ||
|
||
@classmethod | ||
def get_description(cls): | ||
if cls.__doc__ is not None and cls.__doc__ is not '': | ||
return '\n'.join([line.strip() for line in cls.__doc__.split('\n')]) | ||
return 'TODO: Description is still missing from the class docstring.\nStay tuned to have more hint about this variable.' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't like this text - after all, Boolean/Integer etc should speak for themselves. I think this should be: return cls.__name__ |
||
|
||
def original_type(self): | ||
if self.wrapper: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,7 @@ | |
from util import mkdir_p | ||
|
||
import kube_objs | ||
import kube_types | ||
import kube_vartypes | ||
|
||
|
||
|
@@ -209,6 +210,7 @@ def gen_output(self): | |
class PythonBaseFile(object): | ||
_kube_objs = None | ||
_kube_vartypes = None | ||
_kube_type = None | ||
compile_in_init = True | ||
default_export_objects = False | ||
can_cluster_context = True | ||
|
@@ -242,6 +244,26 @@ def get_kube_vartypes(cls): | |
pass | ||
return cls._kube_vartypes | ||
|
||
@classmethod | ||
def get_kube_types(cls): | ||
if cls._kube_type is None: | ||
cls._kube_type = {} | ||
|
||
for k in kube_types.__dict__: | ||
if isinstance(kube_types.__dict__[k], type) and k not in ('KubeType', 'SurgeCheck'): | ||
try: | ||
if hasattr(kube_types.__dict__[k], 'wrapper'): | ||
if kube_types.__dict__[k].wrapper: | ||
if isinstance(kube_types.__dict__[k](kube_types.String), kube_types.KubeType): | ||
cls._kube_type[k] = kube_types.__dict__[k] | ||
else: | ||
if isinstance(kube_types.__dict__[k](), kube_types.KubeType): | ||
cls._kube_type[k] = kube_types.__dict__[k] | ||
except: | ||
pass | ||
|
||
return cls._kube_type | ||
|
||
def __init__(self, collection, path): | ||
if path.basename == '' or path.basename.lower().strip('0123456789abcdefghijklmnopqrstuvwxyz_') != '': | ||
raise UserError(ValueError( | ||
|
@@ -515,6 +537,7 @@ def cluster_info(c): | |
|
||
ret.update(self.__class__.get_kube_objs()) | ||
ret.update(self.__class__.get_kube_vartypes()) | ||
ret.update(self.__class__.get_kube_types()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this needed!? Why do you think you need, say "Integer" or "String" in the DSL? |
||
|
||
self.reserved_names = tuple(ret.keys()) | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -133,3 +133,10 @@ def __str__(self): | |
if self.renderer is None: | ||
return self._internal_render() | ||
return self.renderer(self._internal_render()) | ||
|
||
@classmethod | ||
def get_description(cls): | ||
if cls.__doc__ is not None and cls.__doc__ is not '': | ||
return '\n'.join([line.strip() for line in cls.__doc__.split('\n')]) | ||
return 'TODO: Description is still missing from the class docstring.\nStay tuned to have more hint about this variable.' | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Again return cls.__name__ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I particularly like the name "formats" for vartypes.