core.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. '''
  2. @author: olivier.massot
  3. '''
  4. import re
  5. from path import Path
  6. objects = []
  7. SUBSTR = {92: "\\", 47: "/", 58: ":", 42: "*", 63:"?", 34:"\"", 60:"<", 62:">", 124:"|" }
  8. def path_to_name(path):
  9. name_ = path.name.stripext()
  10. for ascii_code, char in SUBSTR.items():
  11. name_ = name_.replace("[{}]".format(ascii_code), char)
  12. return name_
  13. RXS = {}
  14. def getrx(nom):
  15. try:
  16. return RXS[nom]
  17. except KeyError:
  18. rx = re.compile(r"(?:^|\W)({})(?:$|\W)".format(nom))
  19. RXS[nom] = rx
  20. return rx
  21. def recurse(acc_obj):
  22. deptree = []
  23. for dep in acc_obj.deps:
  24. deptree.append(dep)
  25. if dep.deps:
  26. deptree += recurse(dep)
  27. return deptree
  28. class AccessObject():
  29. def __init__(self, type_, nom, sourcefile):
  30. self.nom = nom
  31. self.type_ = type_
  32. self.functions = []
  33. self.sourcefile = sourcefile
  34. self.deps = []
  35. self.refs = []
  36. def __repr__(self):
  37. return "<{}: {}>".format(self.type_, self.nom)
  38. def add_dep(self, obj):
  39. if not obj in self.deps:
  40. self.deps.append(obj)
  41. def add_ref(self, obj):
  42. if not obj in self.refs:
  43. self.refs.append(obj)
  44. class Analyse():
  45. objects = []
  46. def __enter__(self):
  47. pass
  48. @staticmethod
  49. def report(current, total, msg=""):
  50. pass
  51. @staticmethod
  52. def ended():
  53. pass
  54. @classmethod
  55. def run(cls, source_dir):
  56. source_dir = Path(source_dir)
  57. cls.objects = []
  58. # Liste les objets à partir de l'arborescence du repertoire des sources
  59. cls.report(0, 100, "Analyse du répertoire")
  60. for folder in ["queries", "forms", "relations", "reports", "scripts"]:
  61. for file in Path(source_dir / folder).files("*.bas"):
  62. cls.objects.append(AccessObject(folder, path_to_name(file), file))
  63. for file in Path(source_dir / "tables").files("*.xml") + Path(source_dir / "tables").files("*.lnkd"):
  64. cls.objects.append(AccessObject("tables", path_to_name(file), file))
  65. rx = re.compile(r"Sub|Function ([^(]+)\(")
  66. for file in Path(source_dir / "modules").files("*.bas"):
  67. obj = AccessObject("modules", path_to_name(file), file)
  68. obj.functions = [fname for fname in rx.findall(file.text()) if fname]
  69. cls.objects.append(obj)
  70. total = len(cls.objects)
  71. cls.report(0, total, "> {} objets trouvés".format(total))
  72. # met à jour les dependances en listant les noms d'objets mentionnés dans le fichier subject
  73. for i, subject in enumerate(cls.objects):
  74. cls.report(i, total, "* {}".format(subject.nom))
  75. source = subject.sourcefile.text()
  76. for object_ in cls.objects:
  77. if object_ is subject:
  78. continue
  79. if getrx(object_.nom).search(source):
  80. subject.add_dep(object_)
  81. object_.add_ref(subject)
  82. continue
  83. for fname in object_.functions:
  84. if getrx(fname).search(source):
  85. subject.add_dep(object_)
  86. object_.add_ref(subject)
  87. break
  88. cls.report(total, total, "Analyse terminée")
  89. cls.ended()
  90. return cls.objects
  91. if __name__ == "__main__":
  92. source_dir = Path(r"c:\dev\access\Analytique\source")
  93. here = Path(__file__).parent.abspath()
  94. datafile = here / "access_data.txt"
  95. datafile.remove_p()
  96. def main_report(*_, msg=""):
  97. print(msg)
  98. Analyse.report = main_report
  99. Analyse.run(source_dir)
  100. with open("data.txt", "w+") as f:
  101. for o in Analyse.objects:
  102. f.write("* {} - {}{}\n\tdeps > {}\n".format(o.type_,
  103. o.nom,
  104. "\n\tfunctions > ".format(", ".join(o.functions)) if o.functions else "",
  105. o.deps))
  106. print("# Terminé")