*! version 1.2 20240222 - DIME Analytics & LSMS Team, The World Bank - dimeanalytics@worldbank.org, lsms@worldbank.org cap program drop reproot_search program define reproot_search, rclass qui { version 14.1 syntax , /// path(string) /// recsleft(numlist) /// [ /// skipdirs(string) /// recurse /// ] * Initiate dir counter at 1 local d_count 1 local next_recsleft = `recsleft' - 1 local rootdirs "" local root_file "reproot.yaml" /*************************************************** Initiate things in the original call ***************************************************/ * Start a timer if orginal run. if missing("`recurse'") { * TODO: do not hardcode timer number, find first availible timer clear 68 timer on 68 } /*************************************************** Look for reproot file ***************************************************/ * Test if this location has a root file cap confirm file "`path'/`root_file'" * File found, handle it if (_rc == 0) { noi di as text "{phang}{bf:root:} {it:`path'}{p_end}" local rootdirs `""`path'""' } /*************************************************** Recurse over dirs ***************************************************/ * test if recursion depth is met if (`next_recsleft'>=0) { * List all sub-folders (if any) in this directory cap local dir_list : dir `"`path'"' dirs "*" * Handle file not found error if (_rc == 601) { noi di as text _n "{phang}{red:Warning:} Directory {inp:`path'} could not be searched. Check if the folder path is corrupt. It could also be that the path is longer than what your opertive system can handle.{p_end}" local dir_list "" } *Run command again to throw unandled error to user else if (_rc == 0) local dir_list : dir `"`path'"' dirs "*" * Recure into dirs unless it is part of skip folders foreach dir of local dir_list { if !(`: list dir in skipdirs') { reproot_search, /// path("`path'/`dir'") /// recsleft(`next_recsleft') /// skipdirs(`skipdirs') /// recurse local d_count = `d_count' + `r(num_dir_searched)' if !missing(`"`r(rootdirs)'"') { local rootdirs `"`rootdirs' `r(rootdirs)'"' } } } } /*************************************************** Return number of dirs counted ***************************************************/ return local num_dir_searched `d_count' return local rootdirs `"`rootdirs'"' /*************************************************** If original call, output info ***************************************************/ if missing("`recurse'") { timer off 68 qui timer list 68 return local timer `r(t68)' } } end