10
0
mirror of https://github.com/LCPQ/quantum_package synced 2024-12-23 12:56:14 +01:00
This commit is contained in:
Thomas Applencourt 2015-06-02 18:40:24 +02:00
parent 8bf723dcfc
commit c777891ef5
3 changed files with 122 additions and 89 deletions

View File

@ -19,7 +19,6 @@ except ImportError:
print "source .quantum_package.rc" print "source .quantum_package.rc"
sys.exit(1) sys.exit(1)
# __ # __
# /__ | _ |_ _. | _. ._ o _. |_ | _ _ # /__ | _ |_ _. | _. ._ o _. |_ | _ _
# \_| | (_) |_) (_| | \/ (_| | | (_| |_) | (/_ _> # \_| | (_) |_) (_| | \/ (_| | | (_| |_) | (/_ _>
@ -37,7 +36,8 @@ EZFIO_LIB = join(QPACKAGE_ROOT_EZFIO, "lib", "libezfio.a")
# | # |
Path = namedtuple('Path', ['abs', 'rel']) Path = namedtuple('Path', ['abs', 'rel'])
EZ_config_path = namedtuple('EZ_config', ['path_in_module', 'path_in_ezfio']) EZ_config_path = namedtuple('EZ_config', ['path_in_module', 'path_in_ezfio'])
EZ_handler = namedtuple('EZ_handler', ['ez_module', 'ez_cfg','ez_interface', 'ez_config']) EZ_handler = namedtuple('EZ_handler', ['ez_module', 'ez_cfg', 'ez_interface',
'ez_config'])
Sym_link = namedtuple('Sym_link', ['source', 'destination']) Sym_link = namedtuple('Sym_link', ['source', 'destination'])
@ -52,7 +52,8 @@ def ninja_create_env_variable(pwd_config_file):
""" """
l_string = [] l_string = []
for flag in ["FC", "FCFLAGS", "IRPF90", "IRPF90_FLAGS"]: for flag in ["FC", "FCFLAGS", "IRPF90", "IRPF90_FLAGS"]:
str_ = "{0} = {1}".format(flag, get_compilation_option(pwd_config_file, flag)) str_ = "{0} = {1}".format(flag, get_compilation_option(pwd_config_file,
flag))
l_string.append(str_) l_string.append(str_)
lib_lapack = get_compilation_option(pwd_config_file, "LAPACK_LIB") lib_lapack = get_compilation_option(pwd_config_file, "LAPACK_LIB")
@ -76,19 +77,23 @@ def dict_module_genelogy_path(d_module_genelogy):
d = dict() d = dict()
for module_rel, l_children_rel in d_module_genelogy.iteritems(): for module_rel, l_children_rel in d_module_genelogy.iteritems():
module_abs = join(QPACKAGE_ROOT_SRC, module_rel) module_abs = join(QPACKAGE_ROOT_SRC, module_rel)
p = Path(module_abs, module_rel)
try: try:
d[Path(module_abs, module_rel)] = Path(join(QPACKAGE_ROOT_SRC, l_children_rel), l_children_rel) d[p] = Path(join(QPACKAGE_ROOT_SRC, l_children_rel),
l_children_rel)
except: except:
d[Path(module_abs, module_rel)] = [Path(join(QPACKAGE_ROOT_SRC, children), children) for children in l_children_rel] d[p] = [Path(join(QPACKAGE_ROOT_SRC, children), children)
for children in l_children_rel]
return d return d
# _ __ _ ___ _ _ # _ __ _ ___ _ _
# |_ / |_ | / \ _ _|_ _ # |_ / |_ | / \ _ _|_ _
# |_ /_ | _|_ \_/ o (_ | (_| # |_ /_ | _|_ \_/ o (_ | (_|
# _| # _|
def get_l_module_with_ezfio_cfg(): def get_l_module_with_ezfio_cfg():
""" """
Return all the module who have a EZFIO.cfg Return all the module who have a EZFIO.cfg
@ -97,7 +102,8 @@ def get_l_module_with_ezfio_cfg():
from os.path import isfile, join from os.path import isfile, join
qp_src = QPACKAGE_ROOT_SRC qp_src = QPACKAGE_ROOT_SRC
return [join(qp_src, m) for m in listdir(qp_src) if isfile(join(qp_src, m, "EZFIO.cfg")) ] return [join(qp_src, m) for m in listdir(qp_src)
if isfile(join(qp_src, m, "EZFIO.cfg"))]
def get_l_ezfio_config(): def get_l_ezfio_config():
@ -123,8 +129,7 @@ def ninja_ezfio_cfg_rule():
""" """
l_string = ["rule build_ezfio_interface", l_string = ["rule build_ezfio_interface",
" command = ei_handler.py --path_module $sub_module", " command = ei_handler.py --path_module $sub_module", ""]
""]
return l_string return l_string
@ -133,9 +138,7 @@ def ninja_ezfio_config_rule():
""" """
If a ezfio_config existe you just need to move it If a ezfio_config existe you just need to move it
""" """
l_string = ["rule build_ezfio_config", l_string = ["rule build_ezfio_config", " command = cp $in $out", ""]
" command = cp $in $out",
""]
return l_string return l_string
@ -169,9 +172,7 @@ def get_children_of_ezfio_cfg(l_module_with_ezfio_cfg):
abs_ = join(config_folder, rel) abs_ = join(config_folder, rel)
ez_config = Path(abs_, rel) ez_config = Path(abs_, rel)
l_util[ez_module.rel] = EZ_handler(ez_module, l_util[ez_module.rel] = EZ_handler(ez_module, ez_cfg, ez_interface,
ez_cfg,
ez_interface,
ez_config) ez_config)
return l_util return l_util
@ -187,8 +188,7 @@ def ninja_ezfio_cfg_build(l_util):
for m in l_util.itervalues(): for m in l_util.itervalues():
str_ = "build {1} {2}: build_ezfio_interface {0}" str_ = "build {1} {2}: build_ezfio_interface {0}"
l_string += [str_.format(m.ez_cfg.abs, l_string += [str_.format(m.ez_cfg.abs, m.ez_interface.abs,
m.ez_interface.abs,
m.ez_config.abs)] m.ez_config.abs)]
l_string += [" sub_module = {0}".format(m.ez_module.abs)] l_string += [" sub_module = {0}".format(m.ez_module.abs)]
@ -207,7 +207,8 @@ def ninja_ezfio_config_build(l_ezfio_config):
file_source = m.path_in_module file_source = m.path_in_module
file_create = m.path_in_ezfio file_create = m.path_in_ezfio
l_string += ["build {0}: build_ezfio_config {1}".format(file_create, file_source)] l_string += ["build {0}: build_ezfio_config {1}".format(file_create,
file_source)]
l_string += [""] l_string += [""]
return l_string return l_string
@ -219,9 +220,11 @@ def ninja_ezfio_rule():
Set some variable Set some variable
and run ninja and run ninja
""" """
l_flag = ["export {0}='${0}'".format(flag) for flag in ["FC", "FCFLAGS", "IRPF90"]] l_flag = ["export {0}='${0}'".format(flag)
for flag in ["FC", "FCFLAGS", "IRPF90"]]
l_cmd = ["cd {0}".format(QPACKAGE_ROOT_EZFIO)] + l_flag + ["{0}/ninja/ninja".format(QPACKAGE_ROOT)] l_cmd = ["cd {0}".format(QPACKAGE_ROOT_EZFIO)
] + l_flag + ["{0}/ninja/ninja".format(QPACKAGE_ROOT)]
l_string = ["rule build_ezfio", l_string = ["rule build_ezfio",
" command = {0}".format(" ; ".join(l_cmd)), " command = {0}".format(" ; ".join(l_cmd)),
@ -242,8 +245,7 @@ def ninja_ezfio_build(l_ezfio_config, l_util):
str_ = " ".join(l_ezfio_config + l_ezfio_from_cfg) str_ = " ".join(l_ezfio_config + l_ezfio_from_cfg)
l_string = ["build {0}: build_ezfio {1}".format(EZFIO_LIB, str_), l_string = ["build {0}: build_ezfio {1}".format(EZFIO_LIB, str_), ""]
""]
return l_string return l_string
@ -257,20 +259,15 @@ def get_source_destination(path_module, l_needed_molule):
Return a list of Sym_link = namedtuple('Sym_link', ['source', 'destination']) Return a list of Sym_link = namedtuple('Sym_link', ['source', 'destination'])
for a module for a module
""" """
l = [Sym_link(m.abs, join(QPACKAGE_ROOT_SRC, path_module.rel, m.rel)) for m in l_needed_molule] return [Sym_link(m.abs, join(QPACKAGE_ROOT_SRC, path_module.rel, m.rel))
for m in l_needed_molule]
return l
def ninja_symlink_rule(): def ninja_symlink_rule():
""" """
Return the command to create for the symlink Return the command to create for the symlink
""" """
l_string = ["rule build_symlink", return ["rule build_symlink", " command = ln -sf $in $out", ""]
" command = ln -sf $in $out",
""]
return l_string
def ninja_symlink_build(path_module, l_symlink): def ninja_symlink_build(path_module, l_symlink):
@ -282,12 +279,12 @@ def ninja_symlink_build(path_module, l_symlink):
if not l_symlink: if not l_symlink:
return [] return []
l_string = ["build l_symlink_{0} : phony {1}".format(path_module.rel, " ".join([s.destination for s in l_symlink])), l_string = ["build l_symlink_{0} : phony {1}".format(
""] path_module.rel, " ".join([s.destination for s in l_symlink])), ""]
for symlink in l_symlink: for symlink in l_symlink:
l_string += ["build {0}: build_symlink {1}".format(symlink.destination, symlink.source), l_string += ["build {0}: build_symlink {1}".format(symlink.destination,
""] symlink.source), ""]
return l_string return l_string
@ -301,10 +298,10 @@ def get_l_irp_for_module(path_module_abs):
return the list of irp.f in a module return the list of irp.f in a module
''' '''
dump = [] dump = []
for file in os.listdir(path_module_abs): for f in os.listdir(path_module_abs):
if file.endswith(".irp.f"): if f.endswith(".irp.f"):
dump.append(join(path_module_abs, file)) dump.append(join(path_module_abs, file))
if file == "EZFIO.cfg": if f == "EZFIO.cfg":
dump.append(join(path_module_abs, "ezfio_interface.irp.f")) dump.append(join(path_module_abs, "ezfio_interface.irp.f"))
return dump return dump
@ -331,29 +328,34 @@ def ninja_irpf90_make_rule():
Export the flag and compile Export the flag and compile
Only secontial make a possible Only secontial make a possible
""" """
# ~#~#~#~#~ #
# F l a g s #
# ~#~#~#~#~ #
l_flag = [] l_flag = []
for flag in ["FC", "FCFLAGS", "LIB", "SRC", "OBJ"]: for flag in ["FC", "FCFLAGS", "LIB", "SRC", "OBJ"]:
str_ = "export {0}='${0}'".format(flag) str_ = "export {0}='${0}'".format(flag)
l_flag.append(str_) l_flag.append(str_)
# ~#~#~ #
# c m d #
# ~#~#~ #
l_cmd = ["cd $module"] + l_flag + ["irpf90 $include_dir $IRPF90_FLAGS"] l_cmd = ["cd $module"] + l_flag + ["irpf90 $include_dir $IRPF90_FLAGS"]
l_string = ["pool irp_pool", # ~#~#~#~#~#~ #
" depth = 1", # s t r i n g #
"", # ~#~#~#~#~#~ #
"rule build_irpf90.ninja",
l_string = ["pool irp_pool", " depth = 1", "", "rule build_irpf90.ninja",
" command = {0}".format(" ; ".join(l_cmd)), " command = {0}".format(" ; ".join(l_cmd)),
" pool = irp_pool", " pool = irp_pool", " generator = 1",
" generator = 1", " description = Create the IRP_Tree for $module", ""]
" description = Create the IRP_Tree for $module"
""]
return l_string return l_string
def ninja_irpf90_make_build(path_module, def ninja_irpf90_make_build(path_module, l_needed_molule, d_irp):
l_needed_molule,
d_irp):
""" """
Creatre the dependency for a irpf90.make Creatre the dependency for a irpf90.make
We need all the symklink and all the irp.f We need all the symklink and all the irp.f
@ -362,9 +364,8 @@ def ninja_irpf90_make_build(path_module,
# O u t p u t # # O u t p u t #
# ~#~#~#~#~#~ # # ~#~#~#~#~#~ #
l_creation = [join(path_module.abs, i) for i in ["irpf90.make", l_creation = [join(path_module.abs, i)
"irpf90_entities", for i in ["irpf90.make", "irpf90_entities", "tags",
"tags",
"IRPF90_temp/build.ninja"]] "IRPF90_temp/build.ninja"]]
str_creation = " ".join(l_creation) str_creation = " ".join(l_creation)
@ -374,7 +375,11 @@ def ninja_irpf90_make_build(path_module,
l_irp_need = d_irp[path_module] l_irp_need = d_irp[path_module]
l_destination = ["l_symlink_{0}".format(path_module.rel)] if l_needed_molule else [] if l_needed_molule:
l_destination = ["l_symlink_{0}".format(path_module.rel)]
else:
l_destination = []
str_depend = " ".join(l_irp_need + l_destination) str_depend = " ".join(l_irp_need + l_destination)
# ~#~#~#~#~#~#~#~#~#~#~ # # ~#~#~#~#~#~#~#~#~#~#~ #
@ -384,12 +389,13 @@ def ninja_irpf90_make_build(path_module,
l_src, l_obj = file_dependency(path_module.rel) l_src, l_obj = file_dependency(path_module.rel)
l_include_dir = ["-I {0}".format(m.rel) for m in l_needed_molule] l_include_dir = ["-I {0}".format(m.rel) for m in l_needed_molule]
l_string = ["build {0}: build_irpf90.ninja {1}".format(str_creation, str_depend), l_string = [
"build {0}: build_irpf90.ninja {1}".format(str_creation, str_depend),
" module = {0}".format(path_module.abs), " module = {0}".format(path_module.abs),
" SRC = {0}".format(" ".join(l_src)), " SRC = {0}".format(" ".join(l_src)),
" OBJ = {0}".format(" ".join(l_obj)), " OBJ = {0}".format(" ".join(l_obj)),
" include_dir = {0}".format(" ".join(l_include_dir)), " include_dir = {0}".format(" ".join(l_include_dir)), ""
""] ]
return l_string return l_string
@ -401,8 +407,7 @@ def ninja_readme_rule():
""" """
l_string = ["rule build_readme", l_string = ["rule build_readme",
" command = cd $module ; update_README.py", " command = cd $module ; update_README.py",
" generator = 1", " generator = 1", ""]
""]
return l_string return l_string
@ -415,10 +420,8 @@ def ninja_readme_build(path_module):
path_readme = join(path_module.abs, "README.rst") path_readme = join(path_module.abs, "README.rst")
l_string = ["build {0}: build_readme {1}".format(path_readme, l_string = ["build {0}: build_readme {1}".format(path_readme,
path_irp_man)] path_irp_man),
" module = {0}".format(path_module.abs), ""]
l_string += [" module = {0}".format(path_module.abs)]
l_string += [""]
return l_string return l_string
@ -435,7 +438,10 @@ def get_program(path_module):
try: try:
cmd = 'grep -l "program" {0}/*.irp.f'.format(path_module.abs) cmd = 'grep -l "program" {0}/*.irp.f'.format(path_module.abs)
process = subprocess.Popen([cmd],shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) process = subprocess.Popen([cmd],
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, stderr = process.communicate() stdout, stderr = process.communicate()
except OSError: except OSError:
return [] return []
@ -489,12 +495,19 @@ def ninja_binaries_rule():
Rule for creating the binaries Rule for creating the binaries
""" """
# ~#~#~ #
# c m d #
# ~#~#~ #
l_cmd = ["cd $module/IRPF90_temp", "ninja"] l_cmd = ["cd $module/IRPF90_temp", "ninja"]
# ~#~#~#~#~#~ #
# s t r i n g #
# ~#~#~#~#~#~ #
l_string = ["rule build_binaries", l_string = ["rule build_binaries",
" command = {0}".format(" ; ".join(l_cmd)), " command = {0}".format(" ; ".join(l_cmd)),
" description = Create all the binaries from $module" " description = Create all the binaries from $module", ""]
""]
return l_string return l_string
@ -503,15 +516,22 @@ def ninja_binaries_build(path_module, l_children, d_binaries):
""" """
The binaries need the EZFIO_LIB, and the irpf90.make (aka build.ninja) The binaries need the EZFIO_LIB, and the irpf90.make (aka build.ninja)
""" """
ninja_module_path = join(path_module.abs, "IRPF90_temp", "build.ninja")
# ~#~#~ #
# c m d #
# ~#~#~ #
ninja_module_path = join(path_module.abs, "IRPF90_temp", "build.ninja")
l_abs_bin = [binary.abs for binary in d_binaries[path_module]] l_abs_bin = [binary.abs for binary in d_binaries[path_module]]
# ~#~#~#~#~#~ #
# s t r i n g #
# ~#~#~#~#~#~ #
l_string = ["build {0}: build_binaries {1} {2}".format(" ".join(l_abs_bin), l_string = ["build {0}: build_binaries {1} {2}".format(" ".join(l_abs_bin),
EZFIO_LIB, EZFIO_LIB,
ninja_module_path), ninja_module_path),
" module = {0}".format(path_module.abs), " module = {0}".format(path_module.abs), ""]
""]
return l_string return l_string
@ -524,6 +544,10 @@ def ninja_dot_tree_rule():
""" """
Rule for creating the binaries Rule for creating the binaries
""" """
# ~#~#~ #
# c m d #
# ~#~#~ #
l_cmd = ["cd $module", "module_handler.py create_png"] l_cmd = ["cd $module", "module_handler.py create_png"]
l_string = ["rule build_dot_tree", l_string = ["rule build_dot_tree",
@ -536,13 +560,12 @@ def ninja_dot_tree_rule():
def ninja_dot_tree_build(path_module): def ninja_dot_tree_build(path_module):
l_string = ["build {0}: build_dot_tree".format(join(path_module.abs, "tree_dependency.png")), path_tree = join(path_module.abs, "tree_dependency.png")
" module = {0}".format(path_module.abs), l_string = ["build {0}: build_dot_tree".format(path_tree),
""] " module = {0}".format(path_module.abs), ""]
return l_string return l_string
# #
# |\/| _. o ._ # |\/| _. o ._
# | | (_| | | | # | | (_| | | |
@ -629,7 +652,8 @@ if __name__ == "__main__":
# ~#~#~#~#~#~#~#~ # # ~#~#~#~#~#~#~#~ #
# i r p . f 9 0 # # i r p . f 9 0 #
# ~#~#~#~#~#~#~#~ # # ~#~#~#~#~#~#~#~ #
l_string += ninja_irpf90_make_build(module_to_compile, l_children, d_irp) l_string += ninja_irpf90_make_build(module_to_compile, l_children,
d_irp)
# ~#~#~#~#~#~#~#~ # # ~#~#~#~#~#~#~#~ #
# d o t _ t r e e # # d o t _ t r e e #
@ -641,7 +665,8 @@ if __name__ == "__main__":
# ~#~#~#~#~#~#~ # # ~#~#~#~#~#~#~ #
for module_to_compile in d_binaries_production.keys(): for module_to_compile in d_binaries_production.keys():
l_string += ninja_binaries_build(module_to_compile, l_children, d_binaries_production) l_string += ninja_binaries_build(module_to_compile, l_children,
d_binaries_production)
l_string += ninja_readme_build(module_to_compile) l_string += ninja_readme_build(module_to_compile)
with open(join(QPACKAGE_ROOT, "build.ninja"), "w+") as f: with open(join(QPACKAGE_ROOT, "build.ninja"), "w+") as f:

View File

@ -1,6 +1,5 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """
Create the NEEDED_MODULE Create the NEEDED_MODULE
aka the genealogy (children module, subchildren module and so on), aka the genealogy (children module, subchildren module and so on),
@ -56,12 +55,14 @@ def get_dict_genealogy():
for o in os.listdir(dir_): for o in os.listdir(dir_):
try: try:
with open(os.path.join(dir_, o, "NEEDED_CHILDREN_MODULES"), "r") as f: path_file = os.path.join(dir_, o, "NEEDED_CHILDREN_MODULES")
with open(path_file, "r") as f:
l_children = f.read().split() l_children = f.read().split()
except IOError: except IOError:
continue continue
try: try:
path_file = os.path.join(dir_, o, "Makefile")
with open(os.path.join(dir_, o, "Makefile"), "r") as f: with open(os.path.join(dir_, o, "Makefile"), "r") as f:
data = f.readlines() data = f.readlines()
l_depend = Dependency(get_list_from_makefile(data, "SRC="), l_depend = Dependency(get_list_from_makefile(data, "SRC="),
@ -86,7 +87,7 @@ def him_and_all_children(d_ref, l_module):
try: try:
l.extend(him_and_all_children(d_ref, d_ref[module].l_children)) l.extend(him_and_all_children(d_ref, d_ref[module].l_children))
except KeyError: except KeyError:
print >> sys.stderr, "`{0}` in not a good submodule name".format(module) print >> sys.stderr, "`{0}` not submodule".format(module)
print >> sys.stderr, "Check the corresponding NEEDED_CHILDREN_MODULES" print >> sys.stderr, "Check the corresponding NEEDED_CHILDREN_MODULES"
sys.exit(1) sys.exit(1)
@ -102,7 +103,8 @@ def get_dict_genealogy_desc():
d = {} d = {}
for module_name in d_ref: for module_name in d_ref:
d[module_name] = him_and_all_children(d_ref, d_ref[module_name].l_children) d[module_name] = him_and_all_children(d_ref,
d_ref[module_name].l_children)
return d return d
@ -116,7 +118,8 @@ def get_dict_parent():
d = {} d = {}
for module_name in d_ref: for module_name in d_ref:
d[module_name] = [i for i in d_ref.keys() if module_name in d_ref[i].l_children] d[module_name] = [i for i in d_ref.keys()
if module_name in d_ref[i].l_children]
return d return d
@ -135,7 +138,10 @@ def get_dict_module_boss():
d_module_boss = {} d_module_boss = {}
for module in l_all_module: for module in l_all_module:
d_module_boss[module] = [p for p in l_all_module if module in [p] + d_ref_desc[p] and not d_ref_asc[p]][0] d_module_boss[module] = [
p for p in l_all_module
if module in [p] + d_ref_desc[p] and not d_ref_asc[p]
][0]
return d_module_boss return d_module_boss
@ -155,11 +161,13 @@ def file_dependency(module_name):
d_ref = get_dict_genealogy() d_ref = get_dict_genealogy()
l_src, l_obj = d_ref[module_name].l_dependency l_src, l_obj = d_ref[module_name].l_dependency
l_children_module = him_and_all_children(d_ref, d_ref[module_name].l_children) l_children_module = him_and_all_children(d_ref,
d_ref[module_name].l_children)
for module in l_children_module: for module in l_children_module:
l_src_dump, l_obj_dump = d_ref[module].l_dependency l_src_dump, l_obj_dump = d_ref[module].l_dependency
l_src.extend("{0}/{1}".format(module, i) for i in l_src_dump) l_src.extend("{0}/{1}".format(module, i) for i in l_src_dump)
l_obj.extend("IRPF90_temp/{0}/{1}".format(module, os.path.basename(i)) for i in l_obj_dump) l_obj.extend("IRPF90_temp/{0}/{1}".format(module, os.path.basename(i))
for i in l_obj_dump)
return Dependency(l_src, l_obj) return Dependency(l_src, l_obj)
@ -197,6 +205,7 @@ def create_png(l_module):
path = '{0}.png'.format("tree_dependency") path = '{0}.png'.format("tree_dependency")
graph.write_png(path) graph.write_png(path)
if __name__ == '__main__': if __name__ == '__main__':
arguments = docopt(__doc__) arguments = docopt(__doc__)

View File

@ -1,10 +1,8 @@
#!/usr/bin/env python #!/usr/bin/env python
"""Updates the README.rst file as the include directive is disabled on GitHub.""" """Updates the README.rst file as the include directive is disabled on GitHub."""
__date__ = "Thu Apr 3 23:06:18 CEST 2014" __date__ = "Thu Apr 3 23:06:18 CEST 2014"
__author__ = "Anthony Scemama<scemama@irsamc.ups-tlse.fr> & TApplencourt " __author__ = "Anthony Scemama<scemama@irsamc.ups-tlse.fr> & TApplencourt "
README = "README.rst" README = "README.rst"
Assum_key = "Assumptions\n===========\n" Assum_key = "Assumptions\n===========\n"
Needed_key = "Needed Modules\n==============\n" Needed_key = "Needed Modules\n==============\n"
@ -210,5 +208,6 @@ def main():
except OSError: except OSError:
pass pass
if __name__ == '__main__': if __name__ == '__main__':
main() main()