@@ -140,82 +140,51 @@ func IsExist(path string) (bool, error) {
140140 return false , err
141141}
142142
143- func statDir ( dirPath , recPath string , includeDir , isDirOnly , followSymlinks bool ) ([] string , error ) {
144- dir , err := os .Open (dirPath )
143+ func listDirRecursively ( result * [] string , fsDir , recordParentPath string , opts * ListDirOptions ) error {
144+ dir , err := os .Open (fsDir )
145145 if err != nil {
146- return nil , err
146+ return err
147147 }
148148 defer dir .Close ()
149149
150150 fis , err := dir .Readdir (0 )
151151 if err != nil {
152- return nil , err
152+ return err
153153 }
154154
155- statList := make ([]string , 0 )
156155 for _ , fi := range fis {
157- if CommonSkip (fi .Name ()) {
156+ if opts . SkipCommonHiddenNames && IsCommonHiddenFileName (fi .Name ()) {
158157 continue
159158 }
160-
161- relPath := path .Join (recPath , fi .Name ())
162- curPath := path .Join (dirPath , fi .Name ())
159+ relPath := path .Join (recordParentPath , fi .Name ())
160+ curPath := filepath .Join (fsDir , fi .Name ())
163161 if fi .IsDir () {
164- if includeDir {
165- statList = append (statList , relPath + "/" )
166- }
167- s , err := statDir (curPath , relPath , includeDir , isDirOnly , followSymlinks )
168- if err != nil {
169- return nil , err
170- }
171- statList = append (statList , s ... )
172- } else if ! isDirOnly {
173- statList = append (statList , relPath )
174- } else if followSymlinks && fi .Mode ()& os .ModeSymlink != 0 {
175- link , err := os .Readlink (curPath )
176- if err != nil {
177- return nil , err
178- }
179-
180- isDir , err := IsDir (link )
181- if err != nil {
182- return nil , err
162+ if opts .IncludeDir {
163+ * result = append (* result , relPath + "/" )
183164 }
184- if isDir {
185- if includeDir {
186- statList = append (statList , relPath + "/" )
187- }
188- s , err := statDir (curPath , relPath , includeDir , isDirOnly , followSymlinks )
189- if err != nil {
190- return nil , err
191- }
192- statList = append (statList , s ... )
165+ if err = listDirRecursively (result , curPath , relPath , opts ); err != nil {
166+ return err
193167 }
168+ } else {
169+ * result = append (* result , relPath )
194170 }
195171 }
196- return statList , nil
172+ return nil
197173}
198174
199- // StatDir gathers information of given directory by depth-first.
200- // It returns slice of file list and includes subdirectories if enabled;
201- // it returns error and nil slice when error occurs in underlying functions,
202- // or given path is not a directory or does not exist.
203- //
175+ type ListDirOptions struct {
176+ IncludeDir bool // subdirectories are also included with suffix slash
177+ SkipCommonHiddenNames bool
178+ }
179+
180+ // ListDirRecursively gathers information of given directory by depth-first.
181+ // The paths are always in "dir/slash/file" format (not "\\" even in Windows)
204182// Slice does not include given path itself.
205- // If subdirectories is enabled, they will have suffix '/'.
206- // FIXME: it doesn't like dot-files, for example: "owner/.profile.git"
207- func StatDir (rootPath string , includeDir ... bool ) ([]string , error ) {
208- if isDir , err := IsDir (rootPath ); err != nil {
183+ func ListDirRecursively (rootDir string , opts * ListDirOptions ) (res []string , err error ) {
184+ if err = listDirRecursively (& res , rootDir , "" , opts ); err != nil {
209185 return nil , err
210- } else if ! isDir {
211- return nil , errors .New ("not a directory or does not exist: " + rootPath )
212- }
213-
214- isIncludeDir := false
215- if len (includeDir ) != 0 {
216- isIncludeDir = includeDir [0 ]
217186 }
218- return statDir ( rootPath , "" , isIncludeDir , false , false )
187+ return res , nil
219188}
220189
221190func isOSWindows () bool {
@@ -266,8 +235,8 @@ func HomeDir() (home string, err error) {
266235 return home , nil
267236}
268237
269- // CommonSkip will check a provided name to see if it represents file or directory that should not be watched
270- func CommonSkip (name string ) bool {
238+ // IsCommonHiddenFileName will check a provided name to see if it represents file or directory that should not be watched
239+ func IsCommonHiddenFileName (name string ) bool {
271240 if name == "" {
272241 return true
273242 }
@@ -276,9 +245,9 @@ func CommonSkip(name string) bool {
276245 case '.' :
277246 return true
278247 case 't' , 'T' :
279- return name [1 :] == "humbs.db"
248+ return name [1 :] == "humbs.db" // macOS
280249 case 'd' , 'D' :
281- return name [1 :] == "esktop.ini"
250+ return name [1 :] == "esktop.ini" // Windows
282251 }
283252
284253 return false
0 commit comments