10
0
mirror of https://github.com/LCPQ/quantum_package synced 2024-12-26 22:33:57 +01:00
quantum_package/scripts/module/module_handler.py

310 lines
8.8 KiB
Python
Raw Normal View History

2018-04-30 18:43:13 +02:00
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
2015-06-23 18:43:56 +02:00
Module utilitary
Usage:
2015-06-23 18:43:56 +02:00
module_handler.py print_descendant [<module_name>...]
module_handler.py create_png [<module_name>...]
2015-07-16 11:39:52 +02:00
module_handler.py clean [ --all | <module_name>...]
2015-06-25 16:52:08 +02:00
module_handler.py create_git_ignore [<module_name>...]
Options:
2018-10-19 16:33:58 +02:00
print_descendant Print the genealogy of the needed modules
create_png Create a png of the file
2018-10-19 16:33:58 +02:00
NEED The path of NEED file.
by default try to open the file in the current path
"""
import os
import sys
import os.path
2015-06-25 16:52:08 +02:00
import shutil
2015-05-27 11:02:13 +02:00
2015-06-04 16:40:00 +02:00
try:
from docopt import docopt
2015-07-28 17:31:54 +02:00
from qp_path import QP_SRC, QP_ROOT, QP_PLUGINS
2015-06-04 16:40:00 +02:00
except ImportError:
print "source .quantum_package.rc"
raise
2015-05-27 11:02:13 +02:00
2015-07-28 17:31:54 +02:00
def is_module(path_module_rel):
2018-10-19 16:33:58 +02:00
return os.path.isfile(os.path.join(QP_SRC, path_module_rel, "NEED"))
2015-07-28 17:31:54 +02:00
def is_plugin(path_module_rel):
2018-10-19 16:33:58 +02:00
return os.path.isfile(os.path.join(QP_PLUGINS, path_module_rel, "NEED"))
2015-06-23 18:43:56 +02:00
2015-06-25 16:52:08 +02:00
def is_exe(fpath):
return os.path.isfile(fpath) and os.access(fpath, os.X_OK) and not fpath.endswith(".py")
2015-06-25 16:52:08 +02:00
def get_dict_child(l_root_abs=None):
2018-10-19 16:33:58 +02:00
"""Loop over MODULE in QP_ROOT/src, open all the NEED
and create a dict[MODULE] = [sub module needed, ...]
"""
d_ref = dict()
if not l_root_abs:
2015-06-23 10:04:59 +02:00
l_root_abs = [QP_SRC]
for root_abs in l_root_abs:
for module_rel in os.listdir(root_abs):
module_abs = os.path.join(root_abs, module_rel)
try:
2018-10-19 16:33:58 +02:00
path_file = os.path.join(module_abs, "NEED")
with open(path_file, "r") as f:
l_children = f.read().split()
except IOError:
pass
else:
if module_rel not in d_ref:
d_ref[module_rel] = l_children
else:
print "Module {0} alredy defined"
print "Abort"
sys.exit(1)
2015-05-27 11:02:13 +02:00
return d_ref
def get_l_module_descendant(d_child, l_module):
"""
2015-06-09 15:08:06 +02:00
From a list of module return the module and descendant
"""
l = []
for module in l_module:
if module not in l:
l.append(module)
try:
l.extend(get_l_module_descendant(d_child, d_child[module]))
except KeyError:
2015-07-16 12:15:07 +02:00
print >> sys.stderr, "Error: "
print >> sys.stderr, "`{0}` is not a submodule".format(module)
2015-12-01 12:34:24 +01:00
print >> sys.stderr, "Check the typo (spelling, case, '/', etc.) "
2015-07-16 12:15:07 +02:00
sys.exit(1)
return list(set(l))
class ModuleHandler():
def __init__(self, l_root_abs=None):
self.dict_child = get_dict_child(l_root_abs)
2015-06-02 15:47:24 +02:00
@property
2015-06-04 16:40:00 +02:00
def l_module(self):
return self.dict_child.keys()
2015-06-02 15:47:24 +02:00
@property
2015-06-04 16:40:00 +02:00
def dict_parent(self):
"""
Get a dic of the first parent
"""
d_child = self.dict_child
2015-06-02 15:47:24 +02:00
2015-06-04 16:40:00 +02:00
d = {}
2015-06-02 15:47:24 +02:00
2015-06-04 16:40:00 +02:00
for module_name in d_child:
2015-07-16 11:39:52 +02:00
d[module_name] = [i for i in d_child.keys()
if module_name in d_child[i]]
2015-06-02 15:47:24 +02:00
2015-06-04 16:40:00 +02:00
return d
2015-06-02 15:47:24 +02:00
@property
2015-06-04 16:40:00 +02:00
def dict_descendant(self):
"""
Get a dic of all the genealogy desc (children and all_children)
"""
d = {}
2015-06-02 15:47:24 +02:00
2015-06-04 16:40:00 +02:00
d_child = self.dict_child
2015-06-02 15:47:24 +02:00
2015-06-04 16:40:00 +02:00
for module_name in d_child:
2015-07-16 11:39:52 +02:00
try:
d[module_name] = get_l_module_descendant(d_child,
d_child[module_name])
except KeyError:
2018-10-19 16:33:58 +02:00
print "Check NEED for {0}".format(
2015-07-16 11:39:52 +02:00
module_name)
sys.exit(1)
2015-06-02 15:47:24 +02:00
2015-06-04 16:40:00 +02:00
return d
2015-06-02 15:47:24 +02:00
@property
2015-06-04 16:40:00 +02:00
def dict_root(self):
"""
Return a dict(module_name) = module_boss
The top node in a tree.
"""
d_asc = self.dict_parent
d_desc = self.dict_descendant
2015-06-02 15:47:24 +02:00
2015-06-04 16:40:00 +02:00
l_all_module = self.l_module
2015-06-02 15:47:24 +02:00
2015-06-04 16:40:00 +02:00
dict_root = {}
2015-06-02 15:47:24 +02:00
2015-06-04 16:40:00 +02:00
for module in l_all_module:
2015-07-16 11:39:52 +02:00
dict_root[module] = [p for p in l_all_module
if module in [p] + d_desc[p] and not d_asc[p]
][0]
2015-06-02 15:47:24 +02:00
2015-06-04 16:40:00 +02:00
return dict_root
def l_descendant_unique(self, l_module):
d_desc = self.dict_descendant
2015-06-04 16:40:00 +02:00
d = {}
for module in l_module:
for e in d_desc[module]:
d[e] = 1
2015-06-04 16:40:00 +02:00
return d.keys()
def l_reduce_tree(self, l_module):
2015-06-05 09:50:24 +02:00
"""For a list of module in input return only the root"""
l_d_u = self.l_descendant_unique(l_module)
2015-06-04 16:40:00 +02:00
l_module_reduce = []
for module in l_module:
if module not in l_d_u:
l_module_reduce.append(module)
2015-05-13 18:15:01 +02:00
2015-06-04 16:40:00 +02:00
return l_module_reduce
def create_png(self, l_module):
2015-06-04 16:40:00 +02:00
"""Create the png of the dependency tree for a l_module"""
2015-11-07 11:17:07 +01:00
# Don't update if we are not in the main repository
from is_master_repository import is_master_repository
if not is_master_repository:
return
2015-07-16 14:25:20 +02:00
basename = "tree_dependency"
path = '{0}.png'.format(basename)
2015-07-03 15:07:24 +02:00
2015-07-28 09:46:38 +02:00
from graphviz import Digraph
2015-07-03 15:07:24 +02:00
2015-06-04 16:40:00 +02:00
all_ready_done = []
2015-06-04 16:40:00 +02:00
def draw_module_edge(module, l_children):
"Draw all the module recursifly"
2015-06-04 16:40:00 +02:00
if module not in all_ready_done:
for children in l_children:
# Add Edge
2015-07-16 10:40:57 +02:00
graph.edge(module, children)
2015-06-04 16:40:00 +02:00
# Recurs
draw_module_edge(children, d_ref[children])
all_ready_done.append(module)
2015-07-16 14:25:20 +02:00
graph = Digraph(comment=l_module, format="png", filename=basename)
d_ref = self.dict_child
2015-06-04 16:40:00 +02:00
# Create all the edge
for module in l_module:
2015-07-16 10:40:57 +02:00
graph.node(module, fontcolor="red")
2015-06-04 16:40:00 +02:00
draw_module_edge(module, d_ref[module])
2015-07-28 10:03:14 +02:00
# Try to render the png
# If not just touch it
2015-07-28 09:46:38 +02:00
try:
graph.render(cleanup=True)
except:
with open(path, 'a'):
os.utime(path, None)
return
2015-06-02 18:40:24 +02:00
if __name__ == '__main__':
arguments = docopt(__doc__)
2015-07-16 11:39:52 +02:00
if arguments['--all']:
l_module = [f for f in os.listdir(QP_SRC)
if os.path.isdir(os.path.join(QP_SRC, f))]
elif not arguments['<module_name>']:
dir_ = os.getcwd()
2015-06-23 18:43:56 +02:00
l_module = [os.path.basename(dir_)]
else:
2015-06-23 18:43:56 +02:00
l_module = arguments['<module_name>']
2015-06-23 18:46:09 +02:00
for module in l_module:
if not is_module(module):
2015-06-30 10:10:38 +02:00
print "{0} is not a valide module. Abort".format(module)
2018-10-19 16:33:58 +02:00
print "No NEED in it"
2015-06-23 18:46:09 +02:00
sys.exit(1)
m = ModuleHandler()
2015-06-04 16:40:00 +02:00
if arguments['print_descendant']:
2015-06-23 18:43:56 +02:00
for module in l_module:
print " ".join(sorted(m.l_descendant_unique([module])))
if arguments["create_png"]:
2015-07-28 15:55:13 +02:00
try:
m.create_png(l_module)
except RuntimeError:
pass
2017-04-05 19:07:23 +02:00
except SyntaxError:
2017-04-20 19:07:03 +02:00
print "Warning: The graphviz API dropped support for python 2.6."
2017-04-05 19:07:23 +02:00
pass
2015-06-23 18:43:56 +02:00
2015-06-25 16:52:08 +02:00
if arguments["clean"] or arguments["create_git_ignore"]:
2015-06-24 09:02:22 +02:00
2015-06-25 16:52:08 +02:00
l_dir = ['IRPF90_temp', 'IRPF90_man']
2015-07-16 11:39:52 +02:00
l_file = ["irpf90_entities", "tags", "irpf90.make", "Makefile",
"Makefile.depend", ".ninja_log", ".ninja_deps",
2015-06-25 16:52:08 +02:00
"ezfio_interface.irp.f"]
2015-06-24 09:02:22 +02:00
2015-06-25 16:52:08 +02:00
for module in l_module:
module_abs = os.path.realpath(os.path.join(QP_SRC, module))
l_symlink = m.l_descendant_unique([module])
2015-07-16 11:39:52 +02:00
l_exe = [f for f in os.listdir(module_abs)
if is_exe(os.path.join(module_abs, f))]
2015-06-24 09:02:22 +02:00
2015-06-25 16:52:08 +02:00
if arguments["clean"]:
for f in l_dir:
try:
shutil.rmtree(os.path.join(module_abs, f))
except:
pass
2015-06-24 09:02:22 +02:00
2015-06-25 16:52:08 +02:00
for symlink in l_symlink:
try:
os.unlink(os.path.join(module_abs, symlink))
except:
pass
2015-06-24 12:25:19 +02:00
2015-06-25 16:52:08 +02:00
for f in l_file:
try:
os.remove(os.path.join(module_abs, f))
except:
pass
2015-06-24 12:25:19 +02:00
2015-06-25 16:52:08 +02:00
for f in l_exe:
2015-06-24 12:25:19 +02:00
try:
os.remove(os.path.join(module_abs, f))
except:
pass
2015-06-25 16:52:08 +02:00
if arguments["create_git_ignore"]:
2015-11-07 11:17:07 +01:00
# Don't update if we are not in the main repository
from is_master_repository import is_master_repository
if not is_master_repository:
2017-04-20 19:07:03 +02:00
sys.exit(0)
2015-11-07 11:17:07 +01:00
2015-06-25 16:52:08 +02:00
path = os.path.join(module_abs, ".gitignore")
with open(path, "w+") as f:
f.write("# Automatically created by {0} \n".format(__file__).replace(QP_ROOT,"$QP_ROOT"))
l_text = l_dir + l_file + l_symlink + l_exe
l_text.sort()
f.write("\n".join(l_text))