def build(filepath, use_graph=None, target_dir=None): transform = {} if not DelphiGraph.filepath_is_graph(filepath): fpabs = os.path.abspath(filepath) abspath = os.path.dirname(fpabs) relpath = "." filename = os.path.basename(fpabs) stdlibpath = DelphiCompiler.get_stdlibpath(libonly=True, relative_to=abspath) includepath = ";".join(stdlibpath) if use_graph: dg = DelphiGraph.from_file(use_graph) df = dg.rootnode includepath = prepare_path(dg, use_abspath=abspath) return do_compile(transform, abspath, relpath, filename, includepath, target_dir=target_dir) else: # load from file dg = DelphiGraph.from_file(filepath) df = dg.rootnode targets = df.collect_nodes(lambda n: n.filetype in (FileTypes.Program, FileTypes.Library, FileTypes.Package)) target = targets[0] includepath = prepare_path(dg) try: # XXX seems to be redundant at times, not understood when do_dfm_conversion(transform, dg) exitcode = do_compile( transform, dg.abspath, target.path, target.filename, includepath, target_dir=target_dir ) finally: for (orig, new) in transform.items(): io.rename(new, orig) return exitcode
def trace(self, filepath, maxdepth=None, projview=False): def trace_deps(filepath, searchpath, stdlibpath, unitaliases, depth=0, maxdepth=None): # don't prevent calls on filepaths already in index so as to resolve # cycles properly, but catch these here to return a valid object # for a filepath already known if self.index_has(filepath): return self.index_get(filepath) io.write_next_action("Tracing %s" % os.path.basename(filepath), indent=depth) filepath, exists, filetype = classify_file(filepath, searchpath, stdlibpath) delphifile = self.new_delphifile(filepath, (filepath, exists, filetype)) if exists: searchpath = collect_searchpath(searchpath, delphifile, filepath) unitaliases = collect_unitaliases(unitaliases, delphifile, filepath) finder_function = finder_dispatch.get(filetype) if finder_function: fps = finder_function(open(filepath).read(), parent=delphifile) io.write_result('Found [%s]' % ', '.join(fps), indent=depth) fps = process_filepaths(delphifile.path, unitaliases, fps) if not maxdepth or maxdepth >= depth+1: for fp in fps: delphifile.add_node(trace_deps(fp, searchpath, stdlibpath, unitaliases, depth=depth+1, maxdepth=maxdepth)) return delphifile path, filename = os.path.split(filepath) abspath = os.path.abspath(path) searchpath = [] stdlibpath = DelphiCompiler.get_stdlibpath(relative_to=(path or '.')) finder_dispatch = { FileTypes.DelphiProjectGroup: findProjects, FileTypes.DelphiProject: group(findMainSource, findDelphiCompilerFlags), FileTypes.Program: group(findUses, findIncludes, findResources), FileTypes.Library: group(findUses, findIncludes, findResources), FileTypes.Package: group(findContains, findIncludes, findResources), FileTypes.Unit: group(findUses, findIncludes, findResources), FileTypes.FileInclude: group(findUses, findIncludes, findResources), } if projview: finder_dispatch = { FileTypes.DelphiProjectGroup: findProjects, FileTypes.DelphiProject: findMainSource, } # change cwd to where the file is so that no matter what . is at # runtime the paths of files in the graph will be constant oldcwd = os.getcwd() try: io.safechdir(path) self.index_clear() df = trace_deps(filename, searchpath, stdlibpath, {}, maxdepth=maxdepth) finally: io.safechdir(oldcwd) return DelphiGraph(df, abspath, searchpath, stdlibpath)