wikicr/src/lib/file_tree.cr

52 lines
1.6 KiB
Crystal

# A `FileTree` is a tree structure representing a file with a name and subfiles.
# It is used to map the wiki for the "sitemap" feature.
# TODO: it should be fully replaced by the index
class Wikicr::FileTree
getter name : String
getter files : Array(FileTree)
# Build a FileTree that represents the real structure of the "to_scan"
# It is recursive and may be very time consuming, so there is a limit of depth
#
# ```
# FileTree.build("./data/")
# ```
def self.build(to_scan : String, max_depth : Int = 32) : FileTree
# Stop the recursion
return FileTree.new to_scan if max_depth < 1
# Save the current directory before getting in
dir_current = Dir.current
Dir.cd to_scan
# List the files, and filter them
all_files = Dir.entries "."
all_files.select! { |file| !(file =~ /^\./) }
all_files.sort!
# Separate files and directory
# For the directories, call this function recursively
files = all_files
.select { |file| !File.directory? file }
.map { |file| FileTree.new(file).as(FileTree) }
directories = all_files
.select { |file| File.directory? file }
.map { |file| FileTree.new(file, FileTree.build(file, max_depth - 1).files).as(FileTree) }
# Generate the file with the list of the files and the directories
structure = FileTree.new to_scan, files + directories
# Get out of the parent and return the current directory object
Dir.cd dir_current
structure
end
def initialize(@name, @files = [] of FileTree)
end
# If the file contains other files, then it is a "directory"
def directory? : Bool
!@files.empty?
end
end