TCL: Recursively search subdirectories to source all .tcl files

后端 未结 7 2076
独厮守ぢ
独厮守ぢ 2021-02-14 09:33

I have a main TCL proc that sources tons of other tcl procs in other folders and subsequent subdirectories. For example, in the main proc it has:

source $basepa         


        
7条回答
  •  一向
    一向 (楼主)
    2021-02-14 10:25

    Based on a previous answer, this version handles cycles created by symbolic links and in the process eliminates duplicate files due to symbolic links as well.

    # findFiles
    # basedir - the directory to start looking in
    # pattern - A pattern, as defined by the glob command, that the files must match
    proc findFiles {directory pattern} {
    
        # Fix the directory name, this ensures the directory name is in the
        # native format for the platform and contains a final directory seperator
        set directory [string trimright [file join [file normalize $directory] { }]]
    
        # Starting with the passed in directory, do a breadth first search for
        # subdirectories. Avoid cycles by normalizing all file paths and checking
        # for duplicates at each level.
    
        set directories [list]
        set parents $directory
        while {[llength $parents] > 0} {
    
            # Find all the children at the current level
            set children [list]
            foreach parent $parents {
                set children [concat $children [glob -nocomplain -type {d r} -path $parent *]]
            }
    
            # Normalize the children
            set length [llength $children]
            for {set i 0} {$i < $length} {incr i} {
                lset children $i [string trimright [file join [file normalize [lindex $children $i]] { }]]
            }
    
            # Make the list of children unique
            set children [lsort -unique $children]
    
            # Find the children that are not duplicates, use them for the next level
            set parents [list]
            foreach child $children {
                if {[lsearch -sorted $directories $child] == -1} {
                    lappend parents $child
                }
            }
    
            # Append the next level directories to the complete list
            set directories [lsort -unique [concat $directories $parents]]
        }
    
        # Get all the files in the passed in directory and all its subdirectories
        set result [list]
        foreach directory $directories {
            set result [concat $result [glob -nocomplain -type {f r} -path $directory -- $pattern]]
        }
    
        # Normalize the filenames
        set length [llength $result]
        for {set i 0} {$i < $length} {incr i} {
            lset result $i [file normalize [lindex $result $i]]
        }
    
        # Return only unique filenames
        return [lsort -unique $result]
    }
    

提交回复
热议问题