Fix the most of the coding style issues in Action

parent 2d4a959e
......@@ -20,6 +20,7 @@
# You should have received a copy of the GNU General Public License
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
"""The Action package provides the full set of provided user functionalities"""
from .check import ActionCheck
from .core import ActionCore
......
......@@ -19,6 +19,8 @@
# You should have received a copy of the GNU General Public License
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
"""This module provides the common stuff for the different supported actions"""
import sys
import logging
......@@ -31,30 +33,37 @@ class Action(ActionCheck, ActionCore,
ActionTree, ActionSimulation,
ActionSynthesis,
QsysHwTclUpdate):
"""This is the base class providing the common Action methods"""
def _check_all_fetched_or_quit(self):
"""Check if every module in the pool is fetched"""
if not self.is_everything_fetched():
logging.error("At least one module remains unfetched. "
"Fetching must be done before makefile generation.")
print("\nUnfetched modules:")
print('\n'.join([str(m) for m in self if not m.isfetched]))
sys.exit("\nExiting.")
logging.error(
"Fetching must be done before makefile generation.\n"
"The following modules remains unfetched:\n"
"%s",
"\n".join([str(m) for m in self if not m.isfetched])
)
quit()
def _check_manifest_variable_is_set(self, name):
"""Method to check if a specific manifest variable is set"""
if getattr(self.top_module, name) is None:
logging.error("Variable %s must be set in the manifest to perform current action (%s)"
% (name, self.__class__.__name__))
logging.error(
"Variable %s must be set in the manifest "
"to perform current action (%s)",
name, self.__class__.__name__)
sys.exit("\nExiting")
def _check_manifest_variable_is_equal_to(self, name, value):
ok = False
try:
manifest_value = getattr(self.top_module, name)
if manifest_value == value:
ok = True
except:
pass
if ok is False:
logging.error("Variable %s must be set in the manifest and equal to '%s'." % (name, value))
def _check_manifest_variable_value(self, name, value):
"""Method to check if a manifest variable is set to a specific value"""
variable_match = False
manifest_value = getattr(self.top_module, name)
if manifest_value == value:
variable_match = True
if variable_match is False:
logging.error(
"Variable %s must be set in the manifest and equal to '%s'.",
name, value)
sys.exit("Exiting")
......@@ -19,6 +19,8 @@
# You should have received a copy of the GNU General Public License
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
"""Module providing generic checking actions. This needs to be implemented"""
from __future__ import print_function
import logging
import sys
......@@ -26,14 +28,21 @@ import re
class ActionCheck(object):
"""Class providing the method to check general properties"""
def check_manifest(self):
"""Method that checks the manifest dict"""
logging.warning("Problems with top_module at %s", self.top_module.path)
logging.error("This action is not implemented yet!")
quit()
def check_condition(self):
"""Method that checks if a supplied condition is OK"""
logging.error("This action is not implemented yet!")
quit()
def _compare(local, reference, cond):
"""Function that provides the actual condition line"""
if cond == "==":
return local == reference
elif cond == "<":
......@@ -80,7 +89,7 @@ class ActionCheck(object):
ver = re.sub("[a-zA-Z]", '', ver)
ref = re.sub("[a-zA-Z]", '', ref)
else:
logging.error("Unknown tool: %s" % tool)
logging.error("Unknown tool: %s", tool)
sys.exit("\nExiting")
comparison = _compare(ver, ref, self.env.options.condition)
......
......@@ -19,8 +19,9 @@
# You should have received a copy of the GNU General Public License
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
"""This module provides the core actions to the pool"""
import logging
import sys
import os
import os.path
import time
......@@ -32,8 +33,10 @@ from hdlmake.srcfile import VerilogFile, VHDLFile, NGCFile
from hdlmake.vlog_parser import VerilogPreprocessor
class ActionCore(object):
"""Class that contains the methods for core actions"""
def fetch(self):
"""Fetch the missing required modules from their remote origin"""
top_module = self.get_top_module()
logging.info("Fetching needed modules.")
os.system(top_module.manifest_dict["fetch_pre_cmd"])
......@@ -43,70 +46,89 @@ class ActionCore(object):
def clean(self):
"""Delete the local copy of the fetched modules"""
logging.info("Removing fetched modules..")
remove_list = [m for m in self if m.source in [fetch.GIT, fetch.SVN] and m.isfetched]
remove_list = [mod_aux for mod_aux in self if
mod_aux.source in [fetch.GIT, fetch.SVN] and mod_aux.isfetched]
remove_list.reverse() # we will remove modules in backward order
if len(remove_list):
for m in remove_list:
logging.info("... clean: " + m.url + " [from: " + m.path + "]")
m.remove_dir_from_disk()
for mod_aux in remove_list:
logging.info("... clean: " + mod_aux.url +
" [from: " + mod_aux.path + "]")
mod_aux.remove_dir_from_disk()
else:
logging.info("There are no modules to be removed")
logging.info("Modules cleaned.")
def list_files(self):
unfetched_modules = [m for m in self if not m.isfetched]
for m in unfetched_modules:
logging.warning("List incomplete, module %s has not been fetched!", m)
"""List the files added to the design across the pool hierarchy"""
unfetched_modules = [mod_aux for mod_aux in self
if not mod_aux.isfetched]
for mod_aux in unfetched_modules:
logging.warning(
"List incomplete, module %s has not been fetched!", mod_aux)
file_set = self.build_file_set()
file_list = dep_solver.make_dependency_sorted_list(file_set)
files_str = [f.path for f in file_list]
files_str = [file_aux.path for file_aux in file_list]
if self.env.options.delimiter == None:
delimiter = "\n"
else:
delimiter = self.env.options.delimiter
print(delimiter.join(files_str))
print delimiter.join(files_str)
def _print_comment(self, message):
"""Private method that prints a message to stdout if not terse"""
if not self.env.options.terse:
print message
def _print_file_list(self, file_list):
"""Print file list to standard out"""
if not len(file_list):
self._print_comment("# * This module has no files")
else:
for file_aux in file_list:
print "%s\t%s" % (
path_mod.relpath(file_aux.path), "file")
def list_modules(self):
"""List the modules that are contained by the pool"""
def _convert_to_source_name(source_code):
"""Private function that returns a string with the source type"""
if source_code == fetch.GIT:
return "git"
elif source_code == fetch.SVN:
return "svn"
elif source_code == fetch.LOCAL:
return "local"
elif source_code == fetch.GITSUBMODULE:
return "git_submodule"
terse = self.env.options.terse
for m in self:
if not m.isfetched:
logging.warning("Module not fetched: %s" % m.url)
if not terse: print("# MODULE UNFETCHED! -> %s" % m.url)
for mod_aux in self:
if not mod_aux.isfetched:
logging.warning("Module not fetched: %s", mod_aux.url)
self._print_comment("# MODULE UNFETCHED! -> %s" % mod_aux.url)
else:
if not terse: print("# MODULE START -> %s" % m.url)
if m.source in [fetch.SVN, fetch.GIT]:
if not terse: print("# * URL: "+m.url)
if m.source in [fetch.SVN, fetch.GIT, fetch.LOCAL] and m.parent:
if not terse: print("# * The parent for this module is: %s" % m.parent.url)
self._print_comment("# MODULE START -> %s" % mod_aux.url)
if mod_aux.source in [fetch.SVN, fetch.GIT]:
self._print_comment("# * URL: " + mod_aux.url)
if (mod_aux.source in [fetch.SVN, fetch.GIT, fetch.LOCAL] and
mod_aux.parent):
self._print_comment("# * The parent for this module is: %s"
% mod_aux.parent.url)
else:
if not terse: print("# * This is the root module")
print("%s\t%s" % (path_mod.relpath(m.path), _convert_to_source_name(m.source)))
self._print_comment("# * This is the root module")
print "%s\t%s" % (path_mod.relpath(mod_aux.path),
_convert_to_source_name(mod_aux.source))
if self.env.options.withfiles:
if not len(m.files):
if not terse: print("# * This module has no files")
else:
for f in m.files:
print("%s\t%s" % (path_mod.relpath(f.path), "file"))
if not terse: print("# MODULE END -> %s" % m.url)
if not terse: print("")
self._print_file_list(mod_aux.files)
self._print_comment("# MODULE END -> %s" % mod_aux.url)
self._print_comment("")
def merge_cores(self):
"""Merge the design into a single VHDL and a single Verilog file"""
self._check_all_fetched_or_quit()
logging.info("Merging all cores into one source file per language.")
flist = self.build_file_set()
......@@ -114,14 +136,12 @@ class ActionCore(object):
file_header = (
"\n\n\n\n"
"------------------------------ WARNING -------------------------------\n"
"-- This code has been generated by hdlmake --merge-cores option --\n"
"-- It is provided for your convenience, to spare you from adding --\n"
"-- lots of individual source files to ISE/Modelsim/Quartus projects --\n"
"-- mainly for Windows users. Please DO NOT MODIFY this file. If you --\n"
"-- need to change something inside, edit the original source file --\n"
"-- and re-genrate the merged version! --\n"
"----------------------------------------------------------------------\n"
"------------------------ WARNING --------------------------\n"
"-- This code has been generated by hdlmake merge-cores --\n"
"-- Please DO NOT MODIFY this file. If you need to change --\n"
"-- something inside, edit the original source file and --\n"
"-- re-generate the merged version! --\n"
"-----------------------------------------------------------\n"
"\n\n\n\n"
)
......@@ -133,7 +153,8 @@ class ActionCore(object):
f_out.write("--- Source: %s\n" % vhdl.module.url)
if vhdl.module.revision:
f_out.write("--- Revision: %s\n" % vhdl.module.revision)
f_out.write("--- Last modified: %s\n" % time.ctime(os.path.getmtime(vhdl.path)))
f_out.write("--- Last modified: %s\n" %
time.ctime(os.path.getmtime(vhdl.path)))
f_out.write(open(vhdl.rel_path(), "r").read()+"\n\n")
#print("VHDL: %s" % vhdl.rel_path())
f_out.close()
......@@ -146,7 +167,8 @@ class ActionCore(object):
f_out.write("// Source: %s\n" % vlog.module.url)
if vlog.module.revision:
f_out.write("// Revision: %s\n" % vlog.module.revision)
f_out.write("// Last modified: %s\n" % time.ctime(os.path.getmtime(vlog.path)))
f_out.write("// Last modified: %s\n" %
time.ctime(os.path.getmtime(vlog.path)))
vpp = VerilogPreprocessor()
for include_path in vlog.include_dirs:
vpp.add_path(include_path)
......@@ -158,7 +180,7 @@ class ActionCore(object):
current_path = os.getcwd()
for ngc in flist.filter(NGCFile):
import shutil
logging.info("copying NGC file: %s" % ngc.rel_path())
logging.info("copying NGC file: %s", ngc.rel_path())
shutil.copy(ngc.rel_path(), current_path)
logging.info("Cores merged.")
......@@ -27,22 +27,23 @@ import logging
class QsysHwTclUpdate(object):
def qsys_hw_tcl_update(self):
file_set = self.build_file_set(self.get_top_module().manifest_dict["syn_top"])
file_set = self.build_file_set(
self.get_top_module().manifest_dict["syn_top"])
file_list = dep_solver.make_dependency_sorted_list(file_set)
files_str = [os.path.relpath(f.path) for f in file_list]
file_tcl = []
for fs in files_str:
path, fname = os.path.split(fs)
file_tcl.append("add_fileset_file %s VHDL PATH %s" % (fname, fs))
# mark the last file as the top level file.
# mark the last file as the top level file.
file_tcl[-1] += " TOP_LEVEL_FILE"
file_tcl.append("\n")
hw_tcl_filename = self.get_top_module().manifest_dict["hw_tcl_filename"]
infile = open(hw_tcl_filename,"r")
infile = open(hw_tcl_filename, "r")
inserted = True
out_lines = []
for line in infile.readlines():
......@@ -64,8 +65,7 @@ class QsysHwTclUpdate(object):
logging.info("Old hw.tcl file backed up to %s", hw_tcl_filename_backup)
logging.info("Updating the file list in %s", hw_tcl_filename)
outfile = open(hw_tcl_filename, "w")
outfile.writelines(out_lines)
outfile.close()
......@@ -25,7 +25,6 @@
from __future__ import print_function
import logging
import sys
import importlib
from hdlmake.dep_file import DepFile
#import hdlmake.new_dep_solver as dep_solver
......@@ -90,7 +89,7 @@ class ActionSimulation(
top_module = self.get_top_module()
fset = self.build_file_set(self.get_top_module().manifest_dict["sim_top"])
fset = self.build_file_set(top_module.manifest_dict["sim_top"])
dep_files = fset.filter(DepFile)
#dep_solver.solve(dep_files)
......
......@@ -20,11 +20,12 @@
# You should have received a copy of the GNU General Public License
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
"""This module provides the synthesis functionality to HDLMake"""
from __future__ import print_function
import logging
import sys
import os
import importlib
from hdlmake.srcfile import SourceFileFactory
from hdlmake.util import path
......@@ -36,8 +37,10 @@ from hdlmake.tools import (
class ActionSynthesis(
ToolISE, ToolPlanAhead, ToolVivado,
ToolQuartus, ToolDiamond, ToolLibero):
"""Class providing the public synthesis methods for the user"""
def _load_synthesis_tool(self):
"""Returns a tool_object that provides the synthesis tool interface"""
tool_name = self.get_top_module().manifest_dict["syn_tool"]
if tool_name is "ise":
tool_object = ToolISE()
......@@ -57,6 +60,7 @@ class ActionSynthesis(
def _check_synthesis_makefile(self):
"""Check the manifest contains all the keys for a synthesis makefile"""
# NOTE: top_module is not used in synthesis!!
if not self.get_top_module().manifest_dict["syn_top"]:
logging.error("syn_top variable must be set in the top manifest.")
......@@ -67,19 +71,13 @@ class ActionSynthesis(
def synthesis_makefile(self):
"""Generate a synthesis Makefile for the selected tool"""
self._check_all_fetched_or_quit()
self._generate_synthesis_makefile()
self._check_synthesis_makefile()
def _generate_synthesis_makefile(self):
tool_object = self._load_synthesis_tool()
tool_info = tool_object.get_keys()
if sys.platform == 'cygwin':
bin_name = tool_info['windows_bin']
else:
bin_name = tool_info['linux_bin']
path_key = tool_info['id'] + '_path'
version_key = tool_info['id'] + '_version'
name = tool_info['name']
env = self.env
......@@ -92,38 +90,14 @@ class ActionSynthesis(
tool_path = ""
logging.info("Generating synthesis makefile for " + name)
tool_object.generate_synthesis_makefile(top_mod=self.get_top_module(),
tool_path=tool_path)
tool_object.generate_synthesis_makefile(
top_mod=self.get_top_module(),
tool_path=tool_path)
logging.info("Synthesis makefile generated.")
def _check_synthesis_project(self):
manifest = self.get_top_module().manifest_dict
if not manifest["syn_tool"]:
logging.error("syn_tool variable must be set in the top manifest.")
sys.exit("Exiting")
if not manifest["syn_device"]:
logging.error("syn_device variable must be set in the top manifest.")
sys.exit("Exiting")
if not manifest["syn_grade"]:
logging.error("syn_grade variable must be set in the top manifest.")
sys.exit("Exiting")
if not manifest["syn_package"]:
logging.error("syn_package variable must be set in the top manifest.")
sys.exit("Exiting")
if not manifest["syn_top"]:
logging.error("syn_top variable must be set in the top manifest.")
sys.exit("Exiting")
def synthesis_project(self):
self._check_all_fetched_or_quit()
self._check_synthesis_project()
self._generate_synthesis_project()
def _write_project_vhd(self, tool, version):
"""Create a VHDL file containing a SDB compatible design description"""
from string import Template
from datetime import date
import getpass
......@@ -169,37 +143,63 @@ end sdb_meta_pkg;""")
project_vhd = open("project.vhd", 'w')
date_std_logic_vector = []
import re
import re
for digit in date_string:
date_std_logic_vector.append("{0:04b}".format(int(digit)))
syn_tool_version = version
syn_tool_version = re.sub("\D", "", syn_tool_version)
syn_tool_std_logic_vector = []
for digit in syn_tool_version:
syn_tool_std_logic_vector.append("{0:04b}".format(int(digit)))
filled_template = template.substitute(repo_url=self.top_module.url,
syn_module_name=self.top_module.manifest_dict["syn_top"],
syn_commit_id=self.top_module.revision,
syn_tool_name=tool.upper(),
syn_tool_version="0000"*(8-len(syn_tool_std_logic_vector))+''.join(syn_tool_std_logic_vector),
syn_tool_version_str=syn_tool_version,
syn_date=''.join(date_std_logic_vector),
syn_date_str=date_string,
syn_username=getpass.getuser())
project_vhd.write(filled_template)
syn_tool_version = re.sub(r"\D", "", syn_tool_version)
syn_tool_std_logic_vector = []
for digit in syn_tool_version:
syn_tool_std_logic_vector.append("{0:04b}".format(int(digit)))
template.substitute(
repo_url=self.top_module.url,
syn_module_name=self.top_module.manifest_dict["syn_top"],
syn_commit_id=self.top_module.revision,
syn_tool_name=tool.upper(),
syn_tool_version="0000"*(8-len(syn_tool_std_logic_vector)) +
''.join(syn_tool_std_logic_vector),
syn_tool_version_str=syn_tool_version,
syn_date=''.join(date_std_logic_vector),
syn_date_str=date_string,
syn_username=getpass.getuser())
project_vhd.write(template)
project_vhd.close()
def _check_synthesis_project(self):
"""Check the manifest contains all the keys for a synthesis project"""
manifest = self.get_top_module().manifest_dict
if not manifest["syn_tool"]:
logging.error(
"syn_tool variable must be set in the top manifest.")
sys.exit("Exiting")
if not manifest["syn_device"]:
logging.error(
"syn_device variable must be set in the top manifest.")
sys.exit("Exiting")
if not manifest["syn_grade"]:
logging.error(
"syn_grade variable must be set in the top manifest.")
sys.exit("Exiting")
if not manifest["syn_package"]:
logging.error(
"syn_package variable must be set in the top manifest.")
sys.exit("Exiting")
if not manifest["syn_top"]:
logging.error(
"syn_top variable must be set in the top manifest.")
sys.exit("Exiting")
def synthesis_project(self):
"""Generate a project for the specific synthesis tool"""
self._check_all_fetched_or_quit()
self._check_synthesis_project()
def _generate_synthesis_project(self):
tool_object = self._load_synthesis_tool()
tool_info = tool_object.get_keys()
if sys.platform == 'cygwin':
bin_name = tool_info['windows_bin']
else:
bin_name = tool_info['linux_bin']
path_key = tool_info['id'] + '_path'
version_key = tool_info['id'] + '_version'
name = tool_info['name']
......@@ -212,28 +212,34 @@ end sdb_meta_pkg;""")
if not self.env.options.force:
if self.env[path_key] is None:
logging.error("Can't generate the " + name + " project. " + name + " not found.")
logging.error("Can't generate the " + name + " project. "
+ name + " not found.")
quit()
if version_key not in env or not env[version_key]:
logging.error(name + " version cannot be deduced. Cannot generate " + name + " "
"project file properly. Please use syn_" + id_value + "_version in the manifest "
"or set")
logging.error(name + " version cannot be deduced. Cannot generate "
+ name + " project file properly. Please use syn_"
+ id_value + "_version in the manifest or set")
sys.exit("Exiting")
logging.info("Generating project for " + name + " v. %s" % env[version_key])
if os.path.exists(self.top_module.manifest_dict["syn_project"]) or os.path.exists(self.top_module.manifest_dict["syn_project"] + "." + ext_value):
logging.info("Generating project for " + name + " v. %s",
env[version_key])
if (os.path.exists(self.top_module.manifest_dict["syn_project"]) or
os.path.exists(self.top_module.manifest_dict["syn_project"] + "."
+ ext_value)):
logging.info("Existing project detected: updating...")
update=True
update = True
else:
logging.info("No previous project: creating a new one...")
update=False
update = False
top_mod = self.get_top_module()
fileset = self.build_file_set(top_mod.manifest_dict["syn_top"])
privative_files = tool_object.supported_files(self.build_complete_file_set())
privative_files = tool_object.supported_files(
self.build_complete_file_set())
if privative_files:
logging.info("Privative / non-parseable files detected: %s" % len(privative_files))
logging.info("Privative / non-parseable files detected: %s",
len(privative_files))
fileset.add(privative_files)
sff = SourceFileFactory()
......@@ -245,12 +251,13 @@ end sdb_meta_pkg;""")
tool_object.generate_synthesis_project(update=update,
tool_version=self.env[version_key],
top_mod=self.get_top_module(),
fileset = fileset)
fileset=fileset)
logging.info(name + " project file generated.")
def _check_remote_synthesis(self):
"""Check we have all the variables to run a remote synthesis"""
if not self.top_module.action == "synthesis":
logging.error("action must be equal to \"synthesis\"")
sys.exit("Exiting")
......@@ -261,12 +268,10 @@ end sdb_meta_pkg;""")
def remote_synthesis(self):
"""Generate a Makefile that is able to run a remote synthesis"""
self._check_all_fetched_or_quit()
self._check_remote_synthesis()
self._generate_remote_synthesis_makefile()
def _generate_remote_synthesis_makefile(self):
tool_object = self._load_synthesis_tool()
logging.info("Generating makefile for remote synthesis.")
......@@ -275,14 +280,17 @@ end sdb_meta_pkg;""")
self.env.check_remote_tool(tool_object)
self.env.check_general()
files = self.build_file_set(self.get_top_module().manifest_dict["syn_top"])
files = self.build_file_set(
self.get_top_module().manifest_dict["syn_top"])
sff = SourceFileFactory()
files.add(sff.new(top_mod.manifest_dict["syn_project"], module=self.top_module))
files.add(sff.new(top_mod.manifest_dict["syn_project"],
module=self.top_module))
tool_object.generate_remote_synthesis_makefile(files=files, name=top_mod.manifest_dict["syn_project"][:-5],
cwd=top_mod.url, user=self.env["rsynth_user"],
server=self.env["rsynth_server"])
tool_object.generate_remote_synthesis_makefile(
files=files, name=top_mod.manifest_dict["syn_project"][:-5],
cwd=top_mod.url, user=self.env["rsynth_user"],
server=self.env["rsynth_server"])
logging.info("Remote synthesis makefile generated.")
......
......@@ -19,54 +19,47 @@
# You should have received a copy of the GNU General Public License
# along with Hdlmake. If not, see <http://www.gnu.org/licenses/>.
"""Module providing graph funtionalities to HDLMake"""
from hdlmake.util import path
import logging
class ActionTree(object):
def generate_tree(self):
try:
import networkx as nx
except Exception as e:
logging.error(e)
quit()
unfetched_modules = False
files_str = []
hierarchy = nx.DiGraph()
color_index = 0
"""Class providing methods to create a graph from pool and to analyze it"""
if self.env.options.solved:
logging.warning("This is the solved tree")
else:
for m in self:
if not m.isfetched:
unfetched_modules = True
else:
if m.parent:
hierarchy.add_node(path.relpath(m.path))
hierarchy.add_edge(path.relpath(m.parent.path), path.relpath(m.path))
else:
hierarchy.add_node(path.relpath(m.path))
top_id = path.relpath(m.path)
if self.env.options.withfiles:
if len(m.files):
for f in m.files:
hierarchy.add_edge(path.relpath(m.path), path.relpath(f.path))
color_index += 1
def _generate_tree_web(self, hierarchy, top_id):
"""Create a JSON file containing the graph hierarchy from pool"""
if self.env.options.web:
try:
import json
from networkx.readwrite import json_graph
except ImportError as error_import:
logging.error(error_import)
quit()
data = json_graph.tree_data(hierarchy, root=top_id)
json_string = json.dumps(data)
json_file = open("hierarchy.json", "w")
json_file.write(json_string)
json_file.close()
if unfetched_modules: logging.warning("Some of the modules have not been fetched!")
# Define the program used to write the graphviz:
# Program should be one of:
# twopi, gvcolor, wc, ccomps, tred, sccmap, fdp,
# circo, neato, acyclic, nop, gvpr, dot, sfdp.
def _generate_tree_graphviz(self, hierarchy, top_id):
"""Define the program used to write the graphviz:
Program should be one of:
twopi, gvcolor, wc, ccomps, tred, sccmap, fdp,
circo, neato, acyclic, nop, gvpr, dot, sfdp
"""
if self.env.options.graphviz:
try:
import matplotlib.pyplot as plt
except Exception as e:
logging.error(e)
import networkx as nx
except ImportError as error_import:
logging.error(error_import)
quit()
pos=nx.graphviz_layout(hierarchy, prog=self.env.options.graphviz, root=top_id)
pos = nx.graphviz_layout(hierarchy,
prog=self.env.options.graphviz,
root=top_id)
nx.draw(hierarchy, pos,
with_labels=True,
alpha=0.5,
......@@ -75,18 +68,40 @@ class ActionTree(object):
plt.show()
if self.env.options.web:
try:
import json
from networkx.readwrite import json_graph
except Exception as e:
logging.error(e)
quit()
data = json_graph.tree_data(hierarchy, root=top_id)
s = json.dumps(data)
json_file = open("hierarchy.json", "w")
json_file.write(s)
json_file.close()
def generate_tree(self):
"""Generate the graph from pool and create the requested outcomes"""
try:
import networkx as nx
except ImportError as error_import:
logging.error(error_import)
quit()
unfetched_modules = False
hierarchy = nx.DiGraph()
if self.env.options.solved:
logging.warning("This is the solved tree")
else:
for mod_aux in self:
if not mod_aux.isfetched:
unfetched_modules = True
else:
if mod_aux.parent:
hierarchy.add_node(path.relpath(mod_aux.path))
hierarchy.add_edge(path.relpath(mod_aux.parent.path),
path.relpath(mod_aux.path))
else:
hierarchy.add_node(path.relpath(mod_aux.path))
top_id = path.relpath(mod_aux.path)
if self.env.options.withfiles:
if len(mod_aux.files):
for file_aux in mod_aux.files:
hierarchy.add_edge(path.relpath(mod_aux.path),
path.relpath(file_aux.path))
if unfetched_modules:
logging.warning("Some of the modules have not been fetched!")
self._generate_tree_web(hierarchy, top_id)
self._generate_tree_graphviz(hierarchy, top_id)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment