Skip to content

Instantly share code, notes, and snippets.

@soyo42
Last active September 21, 2017 08:02
Show Gist options
  • Save soyo42/01c3c92aab67c2bc813e to your computer and use it in GitHub Desktop.
Save soyo42/01c3c92aab67c2bc813e to your computer and use it in GitHub Desktop.
Karaf feature tree generator.
this is project name keeper
#!/bin/bash
if [ -z "$1" ]; then
echo "usage:: $0 <project root directory>" >&2
exit 1
fi
SCRIPT_ROOT="$(dirname "$(readlink -f "$0")")"
#echo "${SCRIPT_ROOT}"
echo "digraph featuresDependencies {"
echo 'nforcelabels=true;'
while read fx; do
echo "${fx}" >&2
xsltproc ${SCRIPT_ROOT}/featureDependencies-v1.3.0.xslt ${fx}
xsltproc ${SCRIPT_ROOT}/featureDecoration-v1.3.0.xslt ${fx}
done < <(find $1 -type f -name 'feature*xml' -not -path '*/target/*')
#done < <(cat feature.list)
echo "}"
#!/bin/bash
if [ -z "$1" ]; then
echo "usage:: $0 <project root directory>" >&2
exit 1
fi
SCRIPT_ROOT="$(dirname "$(readlink -f "$0")")"
#echo "${SCRIPT_ROOT}"
echo "digraph featuresDependencies {"
echo 'nforcelabels=true;'
while read fx; do
echo "${fx}" >&2
xsltproc ${SCRIPT_ROOT}/featureDependencies-v1.4.0.xslt ${fx}
xsltproc ${SCRIPT_ROOT}/featureDecoration-v1.4.0.xslt ${fx}
done < <(find $1 -type f -name 'feature*xml' -not -path '*/target/*')
#done < <(cat feature.list)
echo "}"
#!/bin/bash
if [ -z "$1" ]; then
echo "usage:: $0 <project root directory>" >&2
exit 1
fi
SCRIPT_ROOT="$(dirname "$(readlink -f "$0")")"
#echo "${SCRIPT_ROOT}"
echo "digraph featuresDependencies {"
echo 'nforcelabels=true;'
while read fx; do
echo "${fx}" >&2
xsltproc ${SCRIPT_ROOT}/featureDependencies-v1.2.0.xslt ${fx}
xsltproc ${SCRIPT_ROOT}/featureDecoration-v1.2.0.xslt ${fx}
done < <(find $1 -type f -name 'feature*xml' -not -path '*/target/*')
#done < <(cat feature.list)
echo "}"
#!/bin/bash
if [ -z "$1" ]; then
echo "usage:: $0 <project root directory>" >&2
exit 1
fi
SCRIPT_ROOT="$(dirname "$(readlink -f "$0")")"
#echo "${SCRIPT_ROOT}"
echo "digraph featuresDependencies {"
echo 'nforcelabels=true;'
while read fx; do
echo "${fx}" >&2
#xpath -e '/project/parent/artifactId|/project/dependencies' "${fx}"
${SCRIPT_ROOT}/processK4Features.py "${fx}"
#break
done < <(grep -l -E '>(feature-repo|single-feature)-parent<' `find -L "$@" -type f -name 'pom.xml' -not -path '*/target/*'`)
echo "}"
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fx="http://karaf.apache.org/xmlns/features/v1.2.0">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:apply-templates select="//fx:features/fx:feature"/>
</xsl:template>
<xsl:template match="fx:feature">
<xsl:if test="./fx:configfile">
<!-- color features containnig config files -->
<xsl:text> "</xsl:text>
<xsl:value-of select="./@name" />
<xsl:text>" [color="#0000ff"];
</xsl:text>
</xsl:if>
<xsl:if test="./fx:bundle">
<!-- add bundle list under label -->
<xsl:text> "</xsl:text>
<xsl:value-of select="./@name" />
<xsl:text>" [label=&lt;</xsl:text>
<xsl:value-of select="@name" />
<xsl:text>&lt;br/&gt;&lt;font point-size=&quot;10&quot;&gt;</xsl:text>
<xsl:for-each select="./fx:bundle">
<xsl:if test="./@dependency='true'">
<xsl:text>&lt;font color=&quot;gray&quot;&gt;? </xsl:text>
</xsl:if>
<xsl:variable name="bundle_short" select="substring-after(substring-before(./text(), '{'), '/')"/>
<xsl:variable name="length" select="string-length($bundle_short)"/>
<xsl:value-of select="substring($bundle_short, 1, $length - 1)"/>
<xsl:if test="./@dependency='true'">
<xsl:text>&lt;/font&gt;</xsl:text>
</xsl:if>
<xsl:text>&lt;br align=&quot;left&quot;/&gt;</xsl:text>
</xsl:for-each>
<xsl:text>&lt;/font&gt;&gt;];
</xsl:text>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fx="http://karaf.apache.org/xmlns/features/v1.3.0">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:apply-templates select="//fx:features/fx:feature"/>
</xsl:template>
<xsl:template match="fx:feature">
<xsl:if test="./fx:configfile">
<!-- color features containnig config files -->
<xsl:text> "</xsl:text>
<xsl:value-of select="./@name" />
<xsl:text>" [color="#0000ff"];
</xsl:text>
</xsl:if>
<xsl:if test="./fx:bundle">
<!-- add bundle list under label -->
<xsl:text> "</xsl:text>
<xsl:value-of select="./@name" />
<xsl:text>" [label=&lt;</xsl:text>
<xsl:value-of select="@name" />
<xsl:text>&lt;br/&gt;&lt;font point-size=&quot;10&quot;&gt;</xsl:text>
<xsl:for-each select="./fx:bundle">
<xsl:if test="./@dependency='true'">
<xsl:text>&lt;font color=&quot;gray&quot;&gt;? </xsl:text>
</xsl:if>
<xsl:variable name="bundle_short" select="substring-after(substring-before(./text(), '{'), '/')"/>
<xsl:variable name="length" select="string-length($bundle_short)"/>
<xsl:value-of select="substring($bundle_short, 1, $length - 1)"/>
<xsl:if test="./@dependency='true'">
<xsl:text>&lt;/font&gt;</xsl:text>
</xsl:if>
<xsl:text>&lt;br align=&quot;left&quot;/&gt;</xsl:text>
</xsl:for-each>
<xsl:text>&lt;/font&gt;&gt;];
</xsl:text>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fx="http://karaf.apache.org/xmlns/features/v1.4.0">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:apply-templates select="//fx:features/fx:feature"/>
</xsl:template>
<xsl:template match="fx:feature">
<xsl:if test="./fx:configfile">
<!-- color features containnig config files -->
<xsl:text> "</xsl:text>
<xsl:value-of select="./@name" />
<xsl:text>" [color="#0000ff"];
</xsl:text>
</xsl:if>
<xsl:if test="./fx:bundle">
<!-- add bundle list under label -->
<xsl:text> "</xsl:text>
<xsl:value-of select="./@name" />
<xsl:text>" [label=&lt;</xsl:text>
<xsl:value-of select="@name" />
<xsl:text>&lt;br/&gt;&lt;font point-size=&quot;10&quot;&gt;</xsl:text>
<xsl:for-each select="./fx:bundle">
<!-- <xsl:variable name="bundle_short" select="substring-after(substring-before(./text(), '{'), '/')"/> -->
<!-- <xsl:variable name="length" select="string-length($bundle_short)"/> -->
<!-- <xsl:value-of select="substring($bundle_short, 1, $length - 1)"/> -->
<xsl:value-of select="./text()"/>
<xsl:text>&lt;br align=&quot;left&quot;/&gt;</xsl:text>
</xsl:for-each>
<xsl:text>&lt;/font&gt;&gt;];
</xsl:text>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fx="http://karaf.apache.org/xmlns/features/v1.2.0">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:apply-templates select="//fx:features/fx:feature"/>
</xsl:template>
<xsl:template match="fx:feature">
<xsl:variable name="fxName"><xsl:value-of select="./@name" /></xsl:variable>
<xsl:for-each select="./fx:feature">
<xsl:text> "</xsl:text>
<xsl:value-of select="$fxName"/>
<xsl:text>" -> "</xsl:text>
<xsl:value-of select="./text()"/>
<xsl:text>";
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fx="http://karaf.apache.org/xmlns/features/v1.3.0">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:apply-templates select="//fx:features/fx:feature"/>
</xsl:template>
<xsl:template match="fx:feature">
<xsl:variable name="fxName"><xsl:value-of select="./@name" /></xsl:variable>
<xsl:for-each select="./fx:feature">
<xsl:text> "</xsl:text>
<xsl:value-of select="$fxName"/>
<xsl:text>" -> "</xsl:text>
<xsl:value-of select="./text()"/>
<xsl:text>";
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fx="http://karaf.apache.org/xmlns/features/v1.4.0">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:apply-templates select="//fx:features/fx:feature"/>
</xsl:template>
<xsl:template match="fx:feature">
<xsl:variable name="fxName"><xsl:value-of select="./@name" /></xsl:variable>
<xsl:for-each select="./fx:feature">
<xsl:text> "</xsl:text>
<xsl:value-of select="$fxName"/>
<xsl:text>" -> "</xsl:text>
<xsl:value-of select="./text()"/>
<xsl:text>";
</xsl:text>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
# GOAL
# - generate karaf feature tree using graph
#
# REQUIREMENTS
# - xsltproc
# - graphviz
#
# ENVIRONMENT SETUP
# - just create symbolic link to project root (e.g. ln -s <myProjectAbsolutePath> myProject)
# prepare feature tree data (step 1/2)
./analyzeFeatures.sh myProject/ > fxDeps.dot
# generate graph from prepared .dot file into file (step 2/2)
dot fxDeps.dot -O -T png -Gsize="20,20" -Efontsize=10 -Nshape=record -Estyle=dashed -Earrowhead=open
# generate graph from direct pipe input into file or x11 (all in one step)
./analyzeFeatures.sh myProject/ | dot -O -T x11 -Gsize="17,17" -Efontsize=10 -Nshape=record -Estyle=dashed -Earrowhead=ope
# png format
./analyzeFeatures.sh myProject/ | dot -o fxDeps.dot.png -T png -Gsize="17,17" -Efontsize=10 -Nshape=record -Estyle=dashed -Earrowhead=open
# svg format
./analyzeFeatures.sh myProject/ | dot -o fxDeps.dot.svg -T svg -Gsize="17,17" -Efontsize=10 -Nshape=record -Estyle=dashed -Earrowhead=open
# note: the same can be done with all analyzeFeatures*.sh - depending on features type
#!/usr/bin/env python
import sys
from lxml import etree
if len(sys.argv) < 2:
sys.stderr.write('usage:: {0} <k4-feature pom>\n'.format(sys.argv[0]))
sys.exit(1)
POM_NS = {'mvn': 'http://maven.apache.org/POM/4.0.0'}
FEATURES_TYPE = 'features'
MVN_GLUE = ':'
def read_prj_coords(project_tree):
packaging = project_tree.xpath("./mvn:packaging/text()", namespaces=POM_NS)
return [
project_tree.xpath("./mvn:groupId/text()", namespaces=POM_NS)[0],
project_tree.xpath("./mvn:artifactId/text()", namespaces=POM_NS)[0],
'[jar]' if len(packaging) == 0 else packaging[0]+'s'
]
def read_dep_coords(project_tree):
classifier = project_tree.xpath("./mvn:classifier/text()", namespaces=POM_NS)
return [
project_tree.xpath("./mvn:groupId/text()", namespaces=POM_NS)[0],
project_tree.xpath("./mvn:artifactId/text()", namespaces=POM_NS)[0],
'[bundle]' if len(classifier) == 0 else sanitize_brackets(classifier[0])
]
def sanitize_brackets(raw_text):
return raw_text.replace('{', '\{').replace('}', '\}')
def read_parents(project_tree):
return read_prj_coords(project_tree.xpath("./mvn:parent", namespaces=POM_NS)[0])
def read_dependencies(project_tree):
return map(lambda dep: read_dep_coords(dep),
project_tree.xpath("./mvn:dependencies/mvn:dependency", namespaces=POM_NS))
def read_project_tree(root_tree):
return root_tree.xpath("/mvn:project", namespaces=POM_NS)[0]
def fix_group_id(coordinate_dump, parent_group_id):
if coordinate_dump[0].startswith('${'):
coordinate_dump[0] = parent_group_id
return coordinate_dump
with open(sys.argv[1], 'r') as data:
sys.stderr.write('parsing: {0}\n'.format(sys.argv[1]))
featureTree = etree.parse(data)
# read group and parent artifactId
projectTree = read_project_tree(featureTree)
parent = read_parents(projectTree)
#print(parent)
localCoords = read_prj_coords(projectTree)
local_qname = MVN_GLUE.join(localCoords)
sys.stderr.write('local qname: {0}\n'.format(local_qname))
bundles = []
for i in read_dependencies(projectTree):
featureDep = fix_group_id(i, localCoords[0])
dep_qname = MVN_GLUE.join(featureDep)
if featureDep[2] == FEATURES_TYPE:
print('"{0}" -> "{1}";'.format(local_qname, dep_qname))
else:
# direct bundle dependency
bundles.append(dep_qname)
#print('!!! got bundle: {0}'.format(dep_qname))
# print mvn dependency to label
br_left = '<br align="left"/>'
sys.stdout.write('"{0}" [label=<{0}'.format(local_qname))
sys.stdout.write('<font color="gray" point-size="8">{0}&lt;dependency&gt;{0} &lt;groupId&gt;{1}&lt;/groupId&gt;{0}'
' &lt;artifactId&gt;{2}&lt;/artifactId&gt;{0}&lt;/dependency&gt;{0}</font>'
.format(br_left, localCoords[0], localCoords[1]))
if bundles:
sys.stdout.write('<font point-size="10">{0}{1}</font>'
.format(br_left.join(bundles), br_left))
print('>];')
if bundles:
print('"{0}" [color="#0000ff"];'.format(local_qname))
digraph featuresDependencies {
"odl-openflowplugin-all" -> "odl-openflowplugin-southbound";
"odl-openflowplugin-all" -> "odl-openflowplugin-flow-services";
"odl-openflowplugin-all" -> "odl-openflowplugin-flow-services-rest";
"odl-openflowplugin-all" -> "odl-openflowplugin-flow-services-ui";
"odl-openflowplugin-southbound" -> "odl-mdsal-broker";
"odl-openflowplugin-southbound" -> "odl-openflowplugin-nsf-model";
"odl-openflowplugin-southbound" -> "odl-openflowjava-protocol";
"odl-openflowplugin-flow-services" -> "odl-openflowplugin-nsf-services";
"odl-openflowplugin-flow-services" -> "odl-openflowplugin-southbound";
"odl-openflowplugin-flow-services" -> "odl-openflowplugin-app-config-pusher";
"odl-openflowplugin-flow-services" -> "odl-openflowplugin-app-lldp-speaker";
"odl-openflowplugin-nsf-services" -> "odl-mdsal-broker";
"odl-openflowplugin-nsf-services" -> "odl-openflowplugin-nsf-model";
"odl-openflowplugin-nsf-model" -> "odl-yangtools-models";
"odl-openflowplugin-flow-services-rest" -> "odl-openflowplugin-flow-services";
"odl-openflowplugin-flow-services-rest" -> "odl-restconf";
"odl-openflowplugin-flow-services-ui" -> "odl-openflowplugin-flow-services-rest";
"odl-openflowplugin-flow-services-ui" -> "odl-dlux-core";
"odl-openflowplugin-flow-services-ui" -> "odl-mdsal-apidocs";
"odl-openflowplugin-flow-services-ui" -> "odl-mdsal-xsql";
"odl-openflowplugin-drop-test" -> "odl-openflowplugin-flow-services";
"odl-openflowplugin-app-table-miss-enforcer" -> "odl-openflowplugin-southbound";
"odl-openflowplugin-app-config-pusher" -> "odl-openflowplugin-southbound";
"odl-openflowplugin-app-lldp-speaker" -> "odl-openflowplugin-southbound";
"odl-openflowplugin-nxm-extensions" -> "odl-openflowplugin-southbound";
"odl-openflowplugin-adsal-compatibility-all" -> "odl-openflowplugin-adsal-compatibility";
"odl-openflowplugin-adsal-compatibility" -> "odl-mdsal-broker";
"odl-openflowplugin-adsal-compatibility" -> "odl-openflowplugin-nsf-model";
"odl-openflowplugin-adsal-compatibility" -> "odl-adsal-all";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment