core.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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. def __repr__(self):
  36. return "<{}: {}>".format(self.type_, self.nom)
  37. def add_dep(self, obj):
  38. if not obj in self.deps:
  39. self.deps.append(obj)
  40. def to_json(self):
  41. pass
  42. class Analyse():
  43. objects = []
  44. def __enter__(self):
  45. pass
  46. @staticmethod
  47. def report(current, total, msg=""):
  48. pass
  49. @staticmethod
  50. def ended():
  51. pass
  52. @classmethod
  53. def run(cls, source_dir):
  54. source_dir = Path(source_dir)
  55. cls.objects = []
  56. # Liste les objets à partir de l'arborescence du repertoire des sources
  57. cls.report(0, 100, "Analyse du répertoire")
  58. for folder in ["queries", "forms", "relations", "reports", "scripts"]:
  59. for file in Path(source_dir / folder).files("*.bas"):
  60. cls.objects.append(AccessObject(folder, path_to_name(file), file))
  61. for file in Path(source_dir / "tables").files("*.xml") + Path(source_dir / "tables").files("*.lnkd"):
  62. cls.objects.append(AccessObject("tables", path_to_name(file), file))
  63. rx = re.compile(r"Sub|Function ([^(]+)\(")
  64. for file in Path(source_dir / "modules").files("*.bas"):
  65. obj = AccessObject("modules", path_to_name(file), file)
  66. obj.functions = [fname for fname in rx.findall(file.text()) if fname]
  67. cls.objects.append(obj)
  68. total = len(cls.objects)
  69. cls.report(0, total, "> {} objets trouvés".format(total))
  70. # met à jour les dependances en listant les noms d'objets mentionnés dans le fichier subject
  71. for i, subject in enumerate(cls.objects):
  72. cls.report(i, total, "* {}".format(subject.nom))
  73. source = subject.sourcefile.text()
  74. for object_ in cls.objects:
  75. if object_ is subject:
  76. continue
  77. if getrx(object_.nom).search(source):
  78. subject.add_dep(object_)
  79. continue
  80. for fname in object_.functions:
  81. if getrx(fname).search(source):
  82. subject.add_dep(object_)
  83. break
  84. cls.report(total, total, "Analyse terminée")
  85. cls.ended()
  86. return cls.objects
  87. if __name__ == "__main__":
  88. source_dir = Path(r"c:\dev\access\Analytique\source")
  89. here = Path(__file__).parent.abspath()
  90. datafile = here / "access_data.txt"
  91. datafile.remove_p()
  92. def main_report(i, total, msg=""):
  93. print(msg)
  94. Analyse.report = main_report
  95. Analyse.run(source_dir)
  96. with open("data.txt", "w+") as f:
  97. for o in Analyse.objects:
  98. f.write("* {} - {}{}\n\tdeps > {}\n".format(o.type_,
  99. o.nom,
  100. "\n\tfunctions > ".format(", ".join(o.functions)) if o.functions else "",
  101. o.deps))
  102. print("# Terminé")