''' @author: olivier.massot ''' import re from path import Path objects = [] SUBSTR = {92: "\\", 47: "/", 58: ":", 42: "*", 63:"?", 34:"\"", 60:"<", 62:">", 124:"|" } def path_to_name(path): name_ = path.name.stripext() for ascii_code, char in SUBSTR.items(): name_ = name_.replace("[{}]".format(ascii_code), char) return name_ RXS = {} def getrx(nom): try: return RXS[nom] except KeyError: rx = re.compile(r"(?:^|\W)({})(?:$|\W)".format(nom)) RXS[nom] = rx return rx def recurse(acc_obj): deptree = [] for dep in acc_obj.deps: deptree.append(dep) if dep.deps: deptree += recurse(dep) return deptree class AccessObject(): def __init__(self, type_, nom, sourcefile): self.nom = nom self.type_ = type_ self.functions = [] self.sourcefile = sourcefile self.deps = [] self.refs = [] def __repr__(self): return "<{}: {}>".format(self.type_, self.nom) def add_dep(self, obj): if not obj in self.deps: self.deps.append(obj) def add_ref(self, obj): if not obj in self.ref_by: self.refs.append(obj) class Analyse(): objects = [] def __enter__(self): pass @staticmethod def report(current, total, msg=""): pass @staticmethod def ended(): pass @classmethod def run(cls, source_dir): source_dir = Path(source_dir) cls.objects = [] # Liste les objets à partir de l'arborescence du repertoire des sources cls.report(0, 100, "Analyse du répertoire") for folder in ["queries", "forms", "relations", "reports", "scripts"]: for file in Path(source_dir / folder).files("*.bas"): cls.objects.append(AccessObject(folder, path_to_name(file), file)) for file in Path(source_dir / "tables").files("*.xml") + Path(source_dir / "tables").files("*.lnkd"): cls.objects.append(AccessObject("tables", path_to_name(file), file)) rx = re.compile(r"Sub|Function ([^(]+)\(") for file in Path(source_dir / "modules").files("*.bas"): obj = AccessObject("modules", path_to_name(file), file) obj.functions = [fname for fname in rx.findall(file.text()) if fname] cls.objects.append(obj) total = len(cls.objects) cls.report(0, total, "> {} objets trouvés".format(total)) # met à jour les dependances en listant les noms d'objets mentionnés dans le fichier subject for i, subject in enumerate(cls.objects): cls.report(i, total, "* {}".format(subject.nom)) source = subject.sourcefile.text() for object_ in cls.objects: if object_ is subject: continue if getrx(object_.nom).search(source): subject.add_dep(object_) object_.add_ref(subject) continue for fname in object_.functions: if getrx(fname).search(source): subject.add_dep(object_) object_.add_ref(subject) break cls.report(total, total, "Analyse terminée") cls.ended() return cls.objects if __name__ == "__main__": source_dir = Path(r"c:\dev\access\Analytique\source") here = Path(__file__).parent.abspath() datafile = here / "access_data.txt" datafile.remove_p() def main_report(*_, msg=""): print(msg) Analyse.report = main_report Analyse.run(source_dir) with open("data.txt", "w+") as f: for o in Analyse.objects: f.write("* {} - {}{}\n\tdeps > {}\n".format(o.type_, o.nom, "\n\tfunctions > ".format(", ".join(o.functions)) if o.functions else "", o.deps)) print("# Terminé")