add performance analysis tool to view import trees
This commit is contained in:
105
lib/develop/performance/cmd/imports.vsh
Executable file
105
lib/develop/performance/cmd/imports.vsh
Executable file
@@ -0,0 +1,105 @@
|
||||
#!/usr/bin/env -S v -n -w -gc none -no-retry-compilation -cc tcc -d use_openssl -enable-globals run
|
||||
|
||||
import os
|
||||
|
||||
struct ImportNode {
|
||||
name string
|
||||
children []ImportNode
|
||||
}
|
||||
|
||||
// Function to recursively walk through a directory and gather all .v files
|
||||
fn walk_v_files(dir string) []string {
|
||||
mut v_files := []string{}
|
||||
if os.is_dir(dir) || os.is_link(dir) {
|
||||
files := os.ls(dir) or { return [] }
|
||||
for file in files {
|
||||
full_path := os.join_path(dir, file)
|
||||
if os.is_dir(full_path) || os.is_link(full_path) {
|
||||
v_files << walk_v_files(full_path)
|
||||
} else if full_path.ends_with('.v') {
|
||||
v_files << full_path
|
||||
}
|
||||
}
|
||||
}
|
||||
return v_files
|
||||
}
|
||||
|
||||
// Function to extract imports from a .v file
|
||||
fn extract_imports(file_path string) []string {
|
||||
content := os.read_file(file_path) or {
|
||||
println('Failed to read file: $file_path')
|
||||
return []
|
||||
}
|
||||
mut imports := []string{}
|
||||
for line in content.split_into_lines() {
|
||||
if line.starts_with('import ') {
|
||||
// Remove 'import ' and clean inline comments or braces
|
||||
import_line := line[7..].all_before('//').all_before('{').trim_space()
|
||||
if import_line.contains(' ') {
|
||||
imports << import_line.split(',').map(it.trim_space())
|
||||
} else {
|
||||
imports << import_line
|
||||
}
|
||||
}
|
||||
}
|
||||
return imports
|
||||
}
|
||||
|
||||
// Function to find the directory of a module in .vmodules
|
||||
fn find_module_dir(module_name string) string {
|
||||
module_path := module_name.replace('.', os.path_separator)
|
||||
vmodules_path := os.join_path(os.home_dir(), '.vmodules')
|
||||
module_dir := os.join_path(vmodules_path, module_path)
|
||||
if os.is_dir(module_dir) {
|
||||
return module_dir
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
// Function to build a tree of imports, including .vmodules
|
||||
fn build_import_tree(file_path string, mut visited map[string]bool) ImportNode {
|
||||
if file_path in visited {
|
||||
return ImportNode{name: os.base(file_path), children: []}
|
||||
}
|
||||
visited[file_path] = true
|
||||
|
||||
imports := extract_imports(file_path)
|
||||
mut children := []ImportNode{}
|
||||
|
||||
for import_path in imports {
|
||||
// Check if the import is from the current project or .vmodules
|
||||
module_dir := find_module_dir(import_path)
|
||||
if module_dir != '' {
|
||||
module_files := walk_v_files(module_dir)
|
||||
mut module_children := []ImportNode{}
|
||||
for module_file in module_files {
|
||||
child_node := build_import_tree(module_file, mut visited)
|
||||
module_children << child_node
|
||||
}
|
||||
children << ImportNode{name: import_path, children: module_children}
|
||||
} else {
|
||||
children << ImportNode{name: import_path, children: []}
|
||||
}
|
||||
}
|
||||
|
||||
return ImportNode{name: os.base(file_path), children: children}
|
||||
}
|
||||
|
||||
// Function to print the tree of imports
|
||||
fn print_import_tree(node ImportNode, depth int) {
|
||||
println('${' '.repeat(depth)}- ${node.name}')
|
||||
for child in node.children {
|
||||
print_import_tree(child, depth + 1)
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
root_dir := '.' // Replace with your target directory
|
||||
mut visited := map[string]bool{}
|
||||
v_files := walk_v_files(root_dir)
|
||||
|
||||
for v_file in v_files {
|
||||
root_node := build_import_tree(v_file, mut visited)
|
||||
print_import_tree(root_node, 0)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user