Skip to content

Instantly share code, notes, and snippets.

@soyo42
Last active January 10, 2017 14:44
Show Gist options
  • Save soyo42/3baa553d8430f0a2f807 to your computer and use it in GitHub Desktop.
Save soyo42/3baa553d8430f0a2f807 to your computer and use it in GitHub Desktop.
yangTree path dump helper
*.yang
*.txt
*Model
*model
*-api
.pathDigger.input
.??*~
intputYangs=( \
'example1.yang' \
'example2.yang' \
)
this is project name keeper
= What it does? =
parses a bunch of yang files into tree format, search given needle and prints out path to parent element + module
= Requirements =
- pyang (alias pyangRunner.sh or script providing required variables for portable installation)
- python 2.7+
- yang files
= usage =
# first collect links to all involved yang files:
mkdir yangLinks
./createYangLinks.sh <ROOT_OF_PROJECTS> yangLinks
# in order to find all usages of case action (regexp used for '(action)?')
./pathDigger.sh yangLinks '\(action\)\?'
# example output
module: xxx
rpcs:
+---x add-flow
| +--ro input
| | +--ro instructions
| | | +--ro instruction* [order]
| | | +--ro (instruction)?
| | | +--:(apply-actions-case)
| | | | +--ro apply-actions
| | | | +--ro action* [order]
| | | | +--ro (action)?
#!/bin/bash
if [ -z "$2" ]; then
echo "usage:: $0 <root folder with links to all yang files> <needle>"
exit 1
fi
root="$(readlink -f .)"
treeFile="${root}/tree.txt"
. .pathDigger.input
pushd $1
shift
pyang -f tree ${inputYangs[@]} > ${treeFile}
popd > /dev/null
./pathDump.py ${treeFile} "$@"
#!/usr/bin/python
import sys
import re
if len(sys.argv) != 3:
sys.stderr.write('usage: {0} <tree output> <extension needle>\n'.format(sys.argv[0]))
sys.exit(1)
tagRe = re.compile('^([^ :]+):?.*$')
tree = []
needle = re.compile(sys.argv[2])
sys.stderr.write('needle: {0}\n'.format(needle.pattern))
def buildIndentRe(indentSize):
prefix = ''
start = '[ |]'
count = '+'
if indentSize != None:
count = '{{{0}}}'.format(indentSize)
prefix = '^({0}{1})'.format(start, count)
return re.compile('^{0}[+xo]--.+$'.format(prefix))
def collectPathUp(tree, idx, pathLineIndexes):
path = [] #['###'+tree[idx]]
indent = None
parentRe = buildIndentRe(indent)
topTag = 'module'
indentDone = False
subTag = None
finishing = False
for workIdx in range(idx, -1, -1):
i = tree[workIdx]
mach = parentRe.match(i)
if mach:
# seaching tags - above indented lines
if indentDone:
if mach.group(1) == topTag:
# topTag will be stored and exit
finishing = True
elif subTag:
# subTag (not topTag) already stored
continue
else:
# subTag occured for first time -> store
subTag = mach.group(1)
#path.append('[{0}] {1}'.format(indent, i))
#path.append('{0:6d}{1}'.format(workIdx, i))
path.append(i)
pathLineIndexes.add(workIdx)
if finishing:
break
if not indentDone:
indent = len(mach.group(1))
if (indent-1) % 3 != 0:
sys.stderr.write('broken indent [{1}]:\n{0}\n'.format(mach.group(0), indent))
indent -= 3
parentRe = buildIndentRe(indent)
#print(parentRe.pattern)
if indent == 0:
parentRe = tagRe
indentDone = True
return path
with open(sys.argv[1], 'r') as treeFp:
tree = [line for line in treeFp]
counter = 0
pathIndexes = set()
for i in range(len(tree)):
line = tree[i]
if needle.search(line):
if line[0] != ' ':
continue
counter += 1
pathUp = collectPathUp(tree, i, pathIndexes)
pathUp.reverse()
sys.stdout.write('-- {0} --\n'.format(counter))
for pathElement in pathUp:
sys.stdout.write(pathElement)
with open('tree-color.txt', 'w') as treeColor:
for i in range(len(tree)):
line = tree[i]
if i in pathIndexes:
treeColor.write('\033[32;1m{0}\033[0m\n'.format(line.rstrip()))
else:
treeColor.write(line)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment