From 11487cd835e4a0de70eb033d3e2a003844aa9052 Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sat, 7 Sep 2024 00:33:07 -0400 Subject: Clean up and rename dependency tool --- examples/dependencies.tm | 133 --------------------------------------------- examples/tomodeps.tm | 136 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+), 133 deletions(-) delete mode 100644 examples/dependencies.tm create mode 100644 examples/tomodeps.tm diff --git a/examples/dependencies.tm b/examples/dependencies.tm deleted file mode 100644 index 3719e074..00000000 --- a/examples/dependencies.tm +++ /dev/null @@ -1,133 +0,0 @@ -# Show a Tomo dependency graph -use file - -_USAGE := "Usage: dependencies " - -_HELP := " - dependencies: Show a file dependency graph for Tomo source files. - $_USAGE -" - -func get_module_imports_from_file(file:Text, imports:&{Text}, visited_files:&{Text}): - return if visited_files:has(file) - - reader := when LineReader.from_file(file) is Failure(msg): - !! Failed: $msg - return - is Open(reader): reader - - visited_files:add(file) - - while when reader:next_line() is Success(line): - if line:matches($/use {..}.tm/): - local_import := line:replace($/use {..}/, "\1") - resolved := relative_path(resolve_path(local_import, file)) - if resolved != "": - local_import = resolved - get_module_imports_from_file(local_import, imports, visited_files) - else if line:matches($/use {id}/): - other_module := line:replace($/use {..}/, "\1") - imports:add(other_module) - -func get_module_imports_from_module(module:Text)->{Text}: - files_path := resolve_path("~/.local/src/tomo/$module/lib$(module).files") - if files_path == "": - !! couldn't resolve: $files_path - return {:Text} - - when read(files_path) is Failure(msg): - !! couldn't read: $files_path $msg - return {:Text} - is Success(files_content): - imports := {:Text} - visited := {:Text} - for line in files_content:lines(): - line_resolved := resolve_path(line, relative_to="~/.local/src/tomo/$module/") - skip if line_resolved == "" - get_module_imports_from_file(line_resolved, &imports, &visited) - return imports - -func build_module_dependency_graph(module:Text, dependencies:&{Text:@{Text}}): - return if dependencies:has(module) - - module_deps := @{:Text} - dependencies:set(module, module_deps) - - for dep in get_module_imports_from_module(module): - module_deps:add(dep) - build_module_dependency_graph(dep, dependencies) - - -func build_file_dependency_graph(filename:Text, dependencies:&{Text:@{Text}}): - return if dependencies:has(filename) - - reader := when LineReader.from_file(filename) is Failure(msg): - !! Failed: $msg - return - is Open(reader): reader - - file_deps := @{:Text} - dependencies:set(filename, file_deps) - - while when reader:next_line() is Success(line): - if line:matches($/use {..}.tm/): - used_file := line:replace($/use {..}/, "\1") - resolved := relative_path(resolve_path(used_file, filename)) - if resolved != "": - used_file = resolved - - file_deps:add(used_file) - build_file_dependency_graph(used_file, dependencies) - else if line:matches($/use {id}/): - module := line:replace($/use {..}/, "\1") - file_deps:add(module) - build_module_dependency_graph(module, dependencies) - - -func get_dependency_graph(file:Text)->{Text:{Text}}: - graph := {:Text:@{Text}} - resolved := relative_path(file) - build_file_dependency_graph(resolved, &graph) - return {f:deps[] for f,deps in graph} - -func draw_tree(file:Text, dependencies:{Text:{Text}}, already_printed:&{Text}, prefix="", is_last=yes): - color_file := if file:matches($/{id}/): - "$\x1b[34;1m$file$\x1b[m" - else if resolve_path(file) != "": - file - else: - "$\x1b[31;1m$file (could not resolve)$\x1b[m" - - if already_printed:has(file): - say(prefix ++ (if is_last: "└── " else: "├── ") ++ color_file ++ " $\x1b[2m(recursive)$\x1b[m") - return - - say(prefix ++ (if is_last: "└── " else: "├── ") ++ color_file) - already_printed:add(file) - - child_prefix := prefix ++ (if is_last: " " else: "│ ") - - children := dependencies:get(file, {:Text}) - for i,child in children.items: - is_child_last := (i == children.length) - draw_tree(child, dependencies, already_printed, child_prefix, is_child_last) - -func main(files:[Text]): - for f,file in files: - if not file:matches($/{..}.tm/): - say("$\x1b[2mSkipping $file$\x1b[m") - skip - - printed := {:Text} - resolved := relative_path(file) - if resolved != "": - file = resolved - - deps := get_dependency_graph(file) - - say(file) - printed:add(file) - children := deps:get(file, {:Text}) - for i,child in children.items: - is_child_last := (i == children.length) - draw_tree(child, deps, already_printed=&printed, is_last=is_child_last) diff --git a/examples/tomodeps.tm b/examples/tomodeps.tm new file mode 100644 index 00000000..e7066a5a --- /dev/null +++ b/examples/tomodeps.tm @@ -0,0 +1,136 @@ +# Show a Tomo dependency graph +use file + +_USAGE := "Usage: dependencies " + +_HELP := " + dependencies: Show a file dependency graph for Tomo source files. + $_USAGE +" + +func _get_module_imports_from_file(file:Text, imports:&{Text}, visited_files:&{Text}): + return if visited_files:has(file) + + reader := when LineReader.from_file(file) is Failure(msg): + !! Failed: $msg + return + is Open(reader): reader + + visited_files:add(file) + + while when reader:next_line() is Success(line): + if line:matches($/use {..}.tm/): + local_import := line:replace($/use {..}/, "\1") + resolved := relative_path(resolve_path(local_import, file)) + if resolved != "": + local_import = resolved + _get_module_imports_from_file(local_import, imports, visited_files) + else if line:matches($/use {id}/): + other_module := line:replace($/use {..}/, "\1") + imports:add(other_module) + +func _get_module_imports_from_module(module:Text)->{Text}: + files_path := resolve_path("~/.local/src/tomo/$module/lib$(module).files") + if files_path == "": + !! couldn't resolve: $files_path + return {:Text} + + when read(files_path) is Failure(msg): + !! couldn't read: $files_path $msg + return {:Text} + is Success(files_content): + imports := {:Text} + visited := {:Text} + for line in files_content:lines(): + line_resolved := resolve_path(line, relative_to="~/.local/src/tomo/$module/") + skip if line_resolved == "" + _get_module_imports_from_file(line_resolved, &imports, &visited) + return imports + +func _build_module_dependency_graph(module:Text, dependencies:&{Text:@{Text}}): + return if dependencies:has(module) + + module_deps := @{:Text} + dependencies:set(module, module_deps) + + for dep in _get_module_imports_from_module(module): + module_deps:add(dep) + _build_module_dependency_graph(dep, dependencies) + + +func _build_file_dependency_graph(filename:Text, dependencies:&{Text:@{Text}}): + return if dependencies:has(filename) + + reader := when LineReader.from_file(filename) is Failure(msg): + !! Failed: $msg + return + is Open(reader): reader + + file_deps := @{:Text} + dependencies:set(filename, file_deps) + + while when reader:next_line() is Success(line): + if line:matches($/use {..}.tm/): + used_file := line:replace($/use {..}/, "\1") + resolved := relative_path(resolve_path(used_file, filename)) + if resolved != "": + used_file = resolved + + file_deps:add(used_file) + _build_file_dependency_graph(used_file, dependencies) + else if line:matches($/use {id}/): + module := line:replace($/use {..}/, "\1") + file_deps:add(module) + _build_module_dependency_graph(module, dependencies) + + +func get_dependency_graph(file:Text)->{Text:{Text}}: + graph := {:Text:@{Text}} + resolved := relative_path(file) + _build_file_dependency_graph(resolved, &graph) + return {f:deps[] for f,deps in graph} + +func _draw_tree(file:Text, dependencies:{Text:{Text}}, already_printed:&{Text}, prefix="", is_last=yes): + color_file := if file:matches($/{id}/): + "$\x1b[34;1m$file$\x1b[m" + else if resolve_path(file) != "": + file + else: + "$\x1b[31;1m$file (could not resolve)$\x1b[m" + + if already_printed:has(file): + say(prefix ++ (if is_last: "└── " else: "├── ") ++ color_file ++ " $\x1b[2m(recursive)$\x1b[m") + return + + say(prefix ++ (if is_last: "└── " else: "├── ") ++ color_file) + already_printed:add(file) + + child_prefix := prefix ++ (if is_last: " " else: "│ ") + + children := dependencies:get(file, {:Text}) + for i,child in children.items: + is_child_last := (i == children.length) + _draw_tree(child, dependencies, already_printed, child_prefix, is_child_last) + +func draw_tree(file:Text, dependencies:{Text:{Text}}): + printed := {:Text} + resolved := relative_path(file) + if resolved != "": + file = resolved + + say(file) + printed:add(file) + children := dependencies:get(file, {:Text}) + for i,child in children.items: + is_child_last := (i == children.length) + _draw_tree(child, dependencies, already_printed=&printed, is_last=is_child_last) + +func main(files:[Text]): + for f,file in files: + if not file:matches($/{..}.tm/): + say("$\x1b[2mSkipping $file$\x1b[m") + skip + + dependencies := get_dependency_graph(file) + draw_tree(file, dependencies) + -- cgit v1.2.3