def pytest_sessionfinish(session): """ Write out results for each doc collector. """ if session.config.getoption("rst_dir"): if session.config.getoption("rst_write_index"): index = RstCloth() index.title(session.config.getoption("rst_title", "Test Results")) index.newline() index.content(session.config.getoption("rst_desc", "")) index.newline() index.directive(name="toctree", fields=[("includehidden", ""), ("glob", "")]) index.newline() index.content(["*"], 3) index.newline(2) index.write( os.path.join(session.config.getoption("rst_dir"), "index.rst")) results = [] for doc_collector in getattr(session, "doc_collectors", []): results.extend(doc_collector.get_all_results()) doc_collector.write( os.path.join(session.config.getoption("rst_dir"), doc_collector.node_name + ".rst")) # Writes the Overview.rst file. overview_path = os.path.join(session.config.getoption("rst_dir"), "overview.rst") if os.path.exists(overview_path): # Append to existing overview. with open(overview_path, "r") as existing_overview: overview_data = [ x.rstrip() for x in existing_overview.readlines() ] result_rst = RstCloth() result_rst._data = overview_data else: result_rst = RstCloth() result_rst.title("Test Result Table(s)") result_rst.newline() result_rst._add( tabulate( [(x["name"], x["setup"], x.get( "call", "NOTRUN"), x.get("teardown", "NOTRUN")) for x in results], headers=RESULTS_HEADER, tablefmt="rst", )) result_rst.newline(2) result_rst.write( os.path.join(session.config.getoption("rst_dir"), "overview.rst"))
def __init__(self, option): if not isinstance(option, Option): raise TypeError else: self.option = option self.rst = RstCloth()
def generate_hash_file(fn, conf): r = RstCloth() if os.path.exists(fn): with open(fn, 'r') as f: existing = f.read() else: existing = [] commit = conf.git.commit r.directive('|commit| replace', '``{0}``'.format(commit)) try: if r.data == existing[:-1]: logger.info('no new commit(s), not updating {0} ({1})'.format( fn, commit[:10])) return True except TypeError: logger.warning('problem generating {0}, continuing'.format(fn)) if os.path.exists(fn): os.utime(fn, None) else: with open(fn, 'a'): os.utime(fn, None) else: r.write(fn) logger.info('regenerated {0} with new commit hash: {1}'.format( fn, commit[:10]))
def write_rst(self): document_path = normalize_document_path([self.output_dir] + ['images'], extension='.rst') print(document_path) d = RstCloth() d.title('Docker Images') d.newline() d.content('DockHub URL:') d.newline() d.codeblock('https://hub.docker.com/u/pangeo', language='html') d.newline() for image in self.images: d.h3(image) d.newline() conda_list = self.conda_list(image) metadata = {'URL': f'https://hub.docker.com/r/{image}'} metadata.update(self.docker_inspect(image)) id = image.split('/')[1] html = template.render(id=id, conda_list=conda_list, metadata=metadata) d.directive('raw', arg='html', content=html) d.newline() d.write(document_path)
def render_dfn_list(toc_items): r = RstCloth() r.directive('class', 'toc') r.newline() for entry in toc_items: entry.render() idnt = 3 * entry.level if entry.text_only is True: if 'name' in entry: r.definition(entry.name, entry.description, indent=idnt) else: r.content(entry.description, indent=idnt) r.newline() else: if 'name' in entry: dfn_heading = r.role( 'doc', "{0} <{1}>".format(entry.name, entry.file)) else: dfn_heading = r.role('doc', entry.file) if 'description' in entry: description = entry.description else: description = '' r.definition(dfn_heading, description, indent=idnt) r.newline() return r
def render_step_file(input_fn, output_fn, conf): input_fn_base = os.path.basename(input_fn) logger.debug('generating step file for {0}'.format(input_fn_base)) steps = Steps(input_fn) logger.debug('resolved step file input for {0}'.format(input_fn_base)) r = RstCloth() web_output = WebStepsOutput(steps, conf=conf) web_output.render() r.content(web_output.rst.data, indent=0, wrap=False) logger.debug('generated web output for {0}'.format(input_fn_base)) r.directive('only', 'latex') r.newline() print_output = PrintStepsOutput(steps, conf=conf) print_output.render() r.content(print_output.rst.data, indent=3, wrap=False) logger.debug('generated print output for {0}'.format(input_fn_base)) if output_fn is None: output_fn = os.path.splitext(input_fn)[0] + '.rst' r.write(output_fn) logger.debug('wrote step include at {0}'.format(output_fn))
def _build(self): """ Build the RST doc for the current collector. :return: rstcloth.rst object. """ rst = RstCloth() if self.write_toc: self._build_toc(rst) # Write ref target with full node ID # because test names might not be unique, but full IDs should be. rst.ref_target(self.node_id) rst.newline() getattr(rst, SESSION_HEADER_MAP[self.level])(self.node_name) rst.newline() rst.content(doc_prep(self.node_doc)) rst.newline() for item in self.build_order: self._build_section(item, rst) for subdoc in self.children: rst._add(subdoc.emit()) rst.newline(2) return rst
def get_include_statement(include_file): r = RstCloth() r.newline() r.directive('include', include_file) r.newline() return '\n'.join(r.data)
def build_contents(self): self.contents = RstCloth() self.contents.directive('class', 'hidden') self.contents.newline() self.contents.directive('toctree', fields=[('titlesonly', '')], indent=3) self.contents.newline()
def render_options(option, conf): r = RstCloth() if 'program' not in option.replacement: option.replacement['program'] = RstCloth.role('program', option.program) if option.has_field('command'): option.replacement['command'] = RstCloth.role('toolcommand', option.command) if option.directive in ['option']: if len(option.name) > 1 and option.name[0] in ('<', '-'): prefix = '' else: prefix = '--' directive_str = '{prefix}{name}' if option.has_field('args'): directive_str += ' {args}' if option.has_field('aliases'): directive_str += ', {0}'.format(option.aliases) if option.has_field('args'): directive_str += ' {args}' if option.has_field('args'): directive_str = directive_str.format(prefix=prefix, name=option.name, args=option.args) else: directive_str = directive_str.format(prefix=prefix, name=option.name) else: prefix = '' directive_str = option.name if 'role' not in option.replacement: option.replacement['role'] = ':{0}:`{1}{2}`'.format(option.directive, prefix, option.name) option.render() # jinja template render r.directive(option.directive, directive_str) r.newline() indent = 3 if option.has_field('type'): r.content('*Type*: {0}'.format(option.type), indent=indent) r.newline() if option.has_field('default'): r.content('*Default*: {0}'.format(option.default), indent=indent) r.newline() for field in ('pre', 'description', 'content', 'post'): if option.has_field(field) is False: continue else: r.content(getattr(option, field).split('\n'), indent=indent, wrap=False) r.newline() return r
def render_steps(steps, conf): r = RstCloth() header_html = ('<div class="sequence-block">' '<div class="bullet-block">' '<div class="sequence-step">' '{0}' '</div>' '</div>') for idx, step in enumerate(steps.steps): step.render() # run replacements if 'number' not in step: step.number = idx r.directive('only', 'html or dirhtml or singlehtml') r.newline() r.directive(name='raw', arg='html', content=header_html.format(step.number), indent=3) r.newline() if 'heading' in step: r.heading(text=step.heading, char=character_levels[step.level], indent=3) r.newline() render_step_content(step, 3, r) r.directive(name='raw', arg='html', content="</div>", indent=3) r.newline() r.directive('only', 'latex or epub') r.newline() if 'heading' in step: r.heading(text="Step {0}: {1}".format(step.number, step.heading), char=character_levels[step.level], indent=3) r.newline() else: r.heading(text="Step {0}".format(step.number), char=character_levels[step.level], indent=3) r.newline() render_step_content(step, 3, r) return r
def __init__(self, steps, conf): if not isinstance(steps, Steps): raise TypeError else: self.steps = steps self.conf = conf self.current_step = 1 self.rst = RstCloth() self.hook()
def render_apiargs(apiargs, conf): r = RstCloth() r.directive('only', '(html or singlehtml or dirhtml)') render_apiarg_table(r, apiargs) r.directive('only', '(texinfo or latex or epub)') render_apiarg_fields(r, apiargs) return r
def render_glossary(terms): r = RstCloth() r.directive(name="glossary", fields=[("sorted", "")]) r.newline() for term in terms.ordered_content(): r.definition(term.term, term.definition, wrap=False, indent=3) return r
def render_extracts(extract): r = RstCloth() extract.render() if 'style' in extract: r.directive('rst-class', extract.style) r.newline() render_action(extract, indent=0, level=extract.level, r=r) return r
def generate_release_untar(builder, release): r = RstCloth() r.directive('code-block', 'sh', block='header') r.newline(block='header') r.content('tar -zxvf mongodb-{0}-{1}.tgz'.format(builder, release), 3, wrap=False, block='cmd') return r
def render_toctree(toc_items, is_ref=False): r = RstCloth() r.directive('toctree', fields=[('titlesonly', ''), ('hidden', '')]) r.newline() for entry in toc_items: if is_ref is False and 'name' in entry: r.content('{0} <{1}>'.format(entry.name, entry.file), indent=3, wrap=False) else: r.content(entry.file, indent=3, wrap=False) return r
def generate_release_copy(builder, release): r = RstCloth() r.directive('code-block', 'sh', block='header') r.newline(block='header') r.content('mkdir -p mongodb', 3, wrap=False, block='cmd') r.content('cp -R -n mongodb-{0}-{1}/ mongodb'.format(builder, release), 3, wrap=False, block='cmd') return r
def render_releases(release, conf): r = RstCloth() release.replacement = { 'version': conf.version.release, 'branch': conf.version.branch, 'stable': conf.version.stable, } release.render() # run replacements render_action(release, indent=0, level=2, r=r) return r
def render_extracts(extract): r = RstCloth() extract.render() indent = 0 if 'only' in extract: r.directive('only', extract.only, indent=indent) r.newline() indent += 3 if 'style' in extract: r.directive('rst-class', extract.style, indent=indent) r.newline() render_action(extract, indent=indent, level=extract.level, r=r) return r
def render_toctree(toc_items): r = RstCloth() r.directive('class', 'hidden') r.newline() r.directive('toctree', fields=[('titlesonly', '')], indent=3) r.newline() for entry in toc_items: if 'name' in entry: r.content('{0} <{1}>'.format(entry.name, entry.file), indent=6, wrap=False) else: r.content(entry.file, indent=6, wrap=False) return r
def render_apiargs(apiargs): for content in apiargs.ordered_content(): setup_replacements(content) content.render() # run_replacements r = RstCloth() r.directive('only', '(html or singlehtml or dirhtml)') r.newline() render_apiarg_table(r, apiargs) r.newline() r.directive('only', '(texinfo or latex or epub)') r.newline() render_apiarg_fields(r, apiargs) return r
def generate_params(params, fn, conf): r = RstCloth() basename = os.path.basename(fn) params.sort(key=lambda p: p['position']) # Begin by generating the table for web output r.directive('only', '(html or singlehtml or dirhtml)', block='htm') r.newline(block='htm') # { filename: { $name: <param> } } ext_params = {} processed_params = [] for param in params: if 'file' in param: pos = param['position'] if param['file'] not in ext_params: fn, ext = populate_external_param(param['file'], basename, conf.paths.projectroot, conf.paths.source) ext_params[fn] = ext param = ext_params[conf.paths.source + param['file']][param['name']] param['position'] = pos processed_params.append(param) r.content(generate_param_table(processed_params), indent=3, block='html') r.newline(block='htm') # Then generate old-style param fields for non-web output r.directive('only', '(texinfo or latex or epub)', block='tex') r.newline(block='tex') for param in processed_params: key, val = generate_param_fields(param) r.field(name=key, value=val, indent=3, wrap=False, block='tex') r.newline(block='tex') return r
def get_replacements(conf): if "replacement" in conf.system.files.data: mapping = conf.system.files.data.replacement else: return [] r = RstCloth() try: if conf.version.release != "Upcoming": mapping['release-string'] = "-- {0} Release".format(conf.version.release) else: mapping['release-string'] = "\ " except: pass for k, v in mapping.items(): r.replacement(k, v) return r.data
def genModuleDoc(self, mod, ctx): # d.title('Example Use') # d.newline() # d.h2('Contents') # d.directive(name="contents", fields=[('local', ''), ('backlinks', 'None')]) # d.newline() # d.h2('Code -- shebang') # d.codeblock('#!/usr/bin/env') # # d.print_content() mod_r = RstCloth() mod_r.newline() mod_r.h1(mod.module_name) mod_r.newline() if mod.module.attrs.has_key('version'): mod_r.h4("openconfig-version: " + mod.module.attrs['version']) # module description header mod_r.h4("Description") mod_r.newline() # module description text paragraphs = text_to_paragraphs(mod.module.attrs['desc']) for para in paragraphs: mod_r.content(para) mod_r.newline() mod_r.h4("Imports") mod_r.newline() for i in mod.module.attrs['imports']: mod_r.content(i) mod_r.newline() # initialize and store in the module docs print('\n'.join(mod_r._data).encode('utf-8'))
def generate_release_output(builder, platform, architecture, release): """ This is the contemporary version of the function used by the generate.py script""" r = RstCloth() r.directive('code-block', 'sh', block='header') r.newline(block='header') if architecture == 'core': r.content( 'curl -O http://downloads.mongodb.org/{0}/mongodb-{1}-{2}.tgz'. format(platform, builder, release), 3, wrap=False, block='cmd') else: r.content( 'curl -O http://downloads.10gen.com/linux/mongodb-{0}-subscription-{1}-{2}.tgz' .format(builder, architecture, release), 3, wrap=False, block='cmd') r.content('tar -zxvf mongodb-{0}-subscription-{1}-{2}.tgz'.format( builder, architecture, release), 3, wrap=False, block='cmd') r.content('cp -R -n mongodb-{0}-subscription-{1}-{2}/ mongodb'.format( builder, architecture, release), 3, wrap=False, block='cmd') r.newline(block='footer') return r
def generate_param_table(params): table_data = ParamTable() table_data.set_column_widths(params[0]) table_data.add_header( render_header_row(params[0], table_data.num_rows, table_data.type_column)) for param in params: row = [RstCloth().pre(param['name'])] if table_data.type_column is True: row.append(process_type_cell(param['type'], 'table')) row.append( process_description(param['description'], param['field']['optional'])) table_data.add_row(row) table = TableBuilder(ListTable(table_data, widths=table_data.widths)) return table.output
def generate_output(builder, platform, version, release): """ This is the legacy version of the function used by the makefile and CLI infrastructure""" r = RstCloth() r.directive('code-block', 'sh', block='header') r.newline(block='header') if release == 'core': r.content( 'curl -O http://downloads.mongodb.org/{0}/mongodb-{1}-{2}.tgz'. format(platform, builder, version), 3, wrap=False, block='cmd') else: r.content( 'curl -O http://downloads.10gen.com/linux/mongodb-{0}-subscription-{1}-{2}.tgz' .format(builder, release, version), 3, wrap=False, block='cmd') r.content('tar -zxvf mongodb-{0}-subscription-{1}-{2}.tgz'.format( builder, release, version), 3, wrap=False, block='cmd') r.content('cp -R -n mongodb-{0}-subscription-{1}-{2}/ mongodb'.format( builder, release, version), 3, wrap=False, block='cmd') r.newline(block='footer') return r
def generate_image_pages(image, conf): r = RstCloth() dir = image.dir name = image.name alt = image.alt output = image.outputs image = os.path.sep.join([dir, name]) for img_output in output: width = str(img_output.width) + 'px' build_type = img_output.build_type r.newline() if 'tag' in img_output: tag = ''.join(['-', img_output.tag, '.', build_type]) else: tag = '.' + build_type options = [('alt', alt), ('align', 'center'), ('figwidth', width)] if 'scale' in img_output: options.append(('scale', img_output.scale)) if 'target' in img_output: options.append(('target', (img_output.target))) if img_output.type == 'target': continue elif img_output.type == 'print': r.directive('only', 'latex and not offset', wrap=False) r.newline() r.directive(name='figure', arg='/images/{0}{1}'.format(name, tag), fields=options, indent=3) elif img_output.type == 'offset': tex_figure = [ r'\begin{figure}[h!]', r'\centering', ''.join( [r'\includegraphics[width=', width, ']{', name, tag, '}']), r'\end{figure}' ] r.directive('only', 'latex and offset', wrap=False) r.newline() r.directive('raw', 'latex', content=tex_figure, indent=3) else: r.directive('only', 'website and slides', wrap=False) r.newline() r.directive(name='figure', arg='/images/{0}{1}'.format(name, tag), fields=options, indent=3) r.newline() r.directive('only', 'website and html', wrap=False) r.newline() r.directive(name='figure', arg='/images/{0}{1}'.format(name, tag), fields=options, indent=3) r.newline() if img_output.width > 740: options[2] = ('figwidth', '740px') r.directive('only', 'website and not (html or slides)', wrap=False) r.newline() img_str = ''.join([ '<div class="figure align-center" style="max-width:{5};">', '<img src="{0}/{1}/_images/{2}{3}" alt="{4}">', '</img>', '{6}</div>' ]) alt_html = docutils.core.publish_parts( alt, writer_name='html')['body'].strip() r.directive(name='raw', arg='html', content=img_str.format(conf.project.url, conf.git.branches.current, name, tag, alt, width, alt_html), indent=3) r.newline() image_rst_file_path = os.path.join(conf.paths.projectroot, image + '.rst') r.write(image_rst_file_path) logger.info('generated include file {0}.rst'.format(image))
def generate_image_pages(dir, name, alt, output, conf): r = RstCloth() image = '/'.join([dir, name]) b = name for img_output in output: img_output['width'] = str(img_output['width']) + 'px' r.newline() if 'tag' in img_output: tag = '-' + img_output['tag'] + '.png' else: tag = '.png' options = [('alt', alt), ('align', 'center'), ('figwidth', img_output['width'])] if 'scale' in img_output: options.append(('scale', img_output['scale'])) if img_output['type'] == 'print': r.directive('only', 'latex', wrap=False, block=b) r.newline() r.directive(name='figure', arg='/images/{0}{1}'.format(name, tag), fields=options, indent=3, content=alt, block=b) else: alt_html = publish_parts(alt, writer_name='html')['body'].strip() img_tags = [ '<div class="figure align-center" style="max-width:{5};">', '<img src="{0}/{1}/_images/{2}{3}" alt="{4}">', '</img>', '{6}</div>' ] img_str = ''.join(img_tags) r.directive('only', 'website and not html', wrap=False, block=b) r.newline() r.directive(name='raw', arg='html', content=img_str.format(conf.project.url, conf.git.branches.current, name, tag, alt, img_output['width'], alt_html), indent=3, block=b) r.newline(count=2) if img_output['width'] > 600: options[2] = ('figwidth', 600) r.directive('only', 'website and html', wrap=False, block=b) r.newline() r.directive(name='figure', arg='/images/{0}{1}'.format(name, tag), fields=options, indent=3, content=alt, block=b) r.newline(block=b) image_rst_file_path = os.path.join(conf.paths.projectroot, image + '.rst') r.write(image_rst_file_path) logger.info('generated include file {0}.rst'.format(image))