Skip to content
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

Create Github Action for committing and pushing changes to submodules #256

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
0ca0b29
Proto of cell README generator
wgryncewicz Nov 19, 2020
9fcefb0
cell_list generator and lib README patcher
wgryncewicz Nov 19, 2020
c74b4d8
Cell_list now appends links to cell readmes
wgryncewicz Nov 19, 2020
5eb305b
Docs: generate cells documentation in CI
kgugala Nov 20, 2020
9db2820
netlistsvg-generate removed - belongs to another branch
wgryncewicz Nov 25, 2020
b366982
Cell readme generator updated, includes GDS2 layouts
wgryncewicz Nov 25, 2020
10c5e8f
Cell list generator includes cell links in table
wgryncewicz Nov 25, 2020
ab19ce3
Merge branch 'cell_doc_tree' of github.com:antmicro/skywater-pdk into…
wgryncewicz Nov 25, 2020
1f3fcbb
Removed redundant cell_list Sphinx extension script
wgryncewicz Nov 25, 2020
ed83490
Rename cell readme generator script
wgryncewicz Nov 25, 2020
3f498d9
Rename cell list generator script
wgryncewicz Nov 25, 2020
98da26c
Added committing changes made to submodules
glatosinski Nov 23, 2020
550cab4
github-actions: cleaned up generate-rst, added using conda
glatosinski Nov 25, 2020
058f1d0
github-actions: added docutils to requirements.txt
glatosinski Nov 25, 2020
3ecbc35
github-actions: added activating conda environment
glatosinski Nov 25, 2020
43ea361
github-actions: fixed name for cell_readme_generate
glatosinski Nov 25, 2020
c594c49
github-actions: added ignoring failing commits in submodules
glatosinski Nov 25, 2020
6a50169
github-actions: updated script names in generate-rst
glatosinski Nov 25, 2020
4dbb833
github-actions: cleaned up generate-rst
glatosinski Nov 26, 2020
cc86239
github-actions: silenced git commands
glatosinski Nov 26, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Proto of cell README generator
  • Loading branch information
wgryncewicz committed Nov 19, 2020
commit 0ca0b2968ebaae27087922ae774dca0dcff70df4
200 changes: 200 additions & 0 deletions docs/_ext/cell_list.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Copyright 2020 SkyWater PDK Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# SPDX-License-Identifier: Apache-2.0

import argparse
import json
import os
import pathlib
import pprint
import sys
import textwrap
from docutils import nodes
from docutils.parsers.rst import Directive
from docutils.statemachine import ViewList
from sphinx.util.nodes import nested_parse_with_titles

from typing import Tuple, List, Dict

# using a list-table here to allow for easier line breaks in description
rst_header_line_char = '-'
rst_header = 'List of cells in :lib:`{libname}`'
rst_template ="""\
{header_line}
{header_underline}

.. list-table::
:header-rows: 1

* - Cell name
- Description
- Type
- Verilog name
{cell_list}
"""


cell_template = """\
* - {cell_name}
- {description}
- {type}
- {verilog_name}
"""


def collect(library_dir) -> Tuple[str, List[str]]:
"""Collect the available definitions for cells in a library

Parameters
----------
library_dir: str or pathlib.Path
Path to a library.

Returns
-------
lib : str
Library name

cells : list of pathlib.Path
definition files for cells in the library.
"""

if not isinstance(library_dir, pathlib.Path):
library_dir = pathlib.Path(library_dir)

libname = None
cells = set()

for p in library_dir.rglob("definition.json"):
if not p.is_file():
continue
cells.add(p)
if libname is None:
with open(str(p), "r") as sample_json:
sample_def = json.load(sample_json)
libname = sample_def['library']

assert len(libname) > 0
cells = list(sorted(cells))
return libname, cells


def generate_rst(library_dir, library_name, cells):
"""Generate the RST paragraph containing basic information about cells

Parameters
----------
library_dir: str or pathlib.Path
Path to a library.

library_name: str
Name of the library

cells: list of pathlib.Path
List of paths to JSON description files

Returns
-------
paragraph: str
Generated paragraph
"""

if not isinstance(library_dir, pathlib.Path):
library_dir = pathlib.Path(library_dir)

paragraph = ""
cell_list = ""

for cell in cells:
with open(str(cell), "r") as c:
cell_json = json.load(c)
cell_list = cell_list + cell_template.format(
cell_name = cell_json['name'],
#description = cell_json['description'].replace("\n", "\n "),
description = textwrap.indent(cell_json['description'], ' ').lstrip(),
type = cell_json['type'],
verilog_name = cell_json['verilog_name']
)

header = rst_header.format(libname = library_name)
paragraph = rst_template.format(
header_line = header,
header_underline = rst_header_line_char * len(header),
cell_list = cell_list
)
return paragraph

# --- Sphinx extension wrapper ---

class CellList(Directive):

def run(self):
env = self.state.document.settings.env
dirname = env.docname.rpartition('/')[0]
libname, cells = collect(dirname)
paragraph = generate_rst(dirname, libname, cells)
# parse rst string to docutils nodes
rst = ViewList()
for i,line in enumerate(paragraph.split('\n')):
rst.append(line, libname+"-cell-list.rst", i+1)
node = nodes.section()
node.document = self.state.document
nested_parse_with_titles(self.state, rst, node)
return node.children


def setup(app):
app.add_directive("cell_list", CellList)

return {
'version': '0.1',
'parallel_read_safe': True,
'parallel_write_safe': True,
}

# --- stand alone, command line operation ---

def main():
parser = argparse.ArgumentParser()
parser.add_argument(
"library_dir",
help="Path to the library.",
type=pathlib.Path,
nargs=1)

args = parser.parse_args()
lib = args.library_dir[0]

print(f"Analysing {lib}")
libname, cells = collect(lib)
print(f"Library name: {libname}, found {len(cells)} cells")
paragraph = generate_rst(lib, libname, cells)
library_dir = pathlib.Path(lib)
cell_list_file = pathlib.Path(library_dir, "cell-list.rst")
try:
with(open(str(cell_list_file), "w")) as c:
c.write(paragraph)
print(f'Generated {cell_list_file}')
except FileNotFoundError:
print(f"ERROR: Failed to create {str(cell_list_file)}", file=sys.stderr)
raise


if __name__ == "__main__":
sys.exit(main())

130 changes: 130 additions & 0 deletions scripts/python-skywater-pdk/skywater_pdk/cell-readme-generate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
#!/usr/bin/env python3
glatosinski marked this conversation as resolved.
Show resolved Hide resolved
# -*- coding: utf-8 -*-
#
# Copyright 2020 The SkyWater PDK Authors.
#
# Use of this source code is governed by the Apache 2.0
# license that can be found in the LICENSE file or at
# https://www.apache.org/licenses/LICENSE-2.0
#
# SPDX-License-Identifier: Apache-2.0

''' This is a prototype of cell documentation generation script.
WORK IN PROGRESS
'''


import csv
import json
import os
import sys
import argparse
import pathlib
import glob
import subprocess
import textwrap

def write_readme(cellpath, define_data):
''' Generates README for a given cell.
'''
netlist_json = os.path.join(cellpath, define_data['file_prefix']+'.json')
assert os.path.exists(netlist_json), netlist_json
outpath = os.path.join(cellpath, 'README.rst')

header = define_data['name'] + ' cell description'
headline = '-' * len(header)

prefix = define_data['file_prefix']

sym1 = prefix + '.symbol.svg'
sym2 = prefix + '.pp.symbol.svg'
sche = prefix + '.schematic.svg'


with open(outpath, 'w') as f:
f.write (f'{header}\n')
f.write (f'{headline}\n')
f.write ('\nThis is a stub of cell descrition file.\n\n')

f.write (f" * Name: {define_data['name']}\n")
f.write (f" * Type: {define_data['type']}\n")
f.write (f" * Verilog name: {define_data['verilog_name']}\n")
desc = textwrap.indent(define_data['description'], ' ').lstrip(),
f.write (f" * Description: {desc}\n")

f.write ('\nSome sample images:\n')

f.write (f'\n.. image:: {sym1}\n :align: center\n :alt: Symbol\n')
f.write (f'\n.. image:: {sym2}\n :align: center\n :alt: SymbolPP\n')
f.write (f'\n.. image:: {sche}\n :align: center\n :alt: Schematic\n')


def process(cellpath):
''' Processes cell indicated by path.
Opens cell definiton and calls further processing

Args:
cellpath - path to a cell [str of pathlib.Path]
'''

print()
print(cellpath)
define_json = os.path.join(cellpath, 'definition.json')
if not os.path.exists(define_json):
print("No definition.json in", cellpath)
assert os.path.exists(define_json), define_json
define_data = json.load(open(define_json))

if define_data['type'] == 'cell':
write_readme(cellpath, define_data)

return


def main():
''' Generates README.rst for cell.'''

prereq_txt = ''
output_txt = 'output:\n generates README.rst'
allcellpath = '../../../libraries/*/latest/cells/*'

parser = argparse.ArgumentParser(
description = main.__doc__,
epilog = prereq_txt +'\n\n'+ output_txt,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument(
"--all_libs",
help="process all cells in "+allcellpath,
action="store_true")
parser.add_argument(
"cell_dir",
help="path to the cell directory",
type=pathlib.Path,
nargs="*")

args = parser.parse_args()

if args.all_libs:
path = pathlib.Path(allcellpath).expanduser()
parts = path.parts[1:] if path.is_absolute() else path.parts
paths = pathlib.Path(path.root).glob(str(pathlib.Path("").joinpath(*parts)))
args.cell_dir = list(paths)

cell_dirs = [d.resolve() for d in args.cell_dir if d.is_dir()]

errors = 0
for d in cell_dirs:
try:
process(d)
except KeyboardInterrupt:
sys.exit(1)
except (AssertionError, FileNotFoundError, ChildProcessError) as ex:
print (f'Error: {type(ex).__name__}')
print (f'{ex.args}')
errors +=1
print (f'\n{len(cell_dirs)} files processed, {errors} errors.')
return 0 if errors else 1

if __name__ == "__main__":
sys.exit(main())

Loading