github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/Unknwon/com/dir.go (about) 1 // Copyright 2013 com authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"): you may 4 // not use this file except in compliance with the License. You may obtain 5 // a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12 // License for the specific language governing permissions and limitations 13 // under the License. 14 15 package com 16 17 import ( 18 "errors" 19 "fmt" 20 "os" 21 "path" 22 "strings" 23 ) 24 25 // IsDir returns true if given path is a directory, 26 // or returns false when it's a file or does not exist. 27 func IsDir(dir string) bool { 28 f, e := os.Stat(dir) 29 if e != nil { 30 return false 31 } 32 return f.IsDir() 33 } 34 35 func statDir(dirPath, recPath string, includeDir, isDirOnly bool) ([]string, error) { 36 dir, err := os.Open(dirPath) 37 if err != nil { 38 return nil, err 39 } 40 defer dir.Close() 41 42 fis, err := dir.Readdir(0) 43 if err != nil { 44 return nil, err 45 } 46 47 statList := make([]string, 0) 48 for _, fi := range fis { 49 if strings.Contains(fi.Name(), ".DS_Store") { 50 continue 51 } 52 53 relPath := path.Join(recPath, fi.Name()) 54 curPath := path.Join(dirPath, fi.Name()) 55 if fi.IsDir() { 56 if includeDir { 57 statList = append(statList, relPath+"/") 58 } 59 s, err := statDir(curPath, relPath, includeDir, isDirOnly) 60 if err != nil { 61 return nil, err 62 } 63 statList = append(statList, s...) 64 } else if !isDirOnly { 65 statList = append(statList, relPath) 66 } 67 } 68 return statList, nil 69 } 70 71 // StatDir gathers information of given directory by depth-first. 72 // It returns slice of file list and includes subdirectories if enabled; 73 // it returns error and nil slice when error occurs in underlying functions, 74 // or given path is not a directory or does not exist. 75 // 76 // Slice does not include given path itself. 77 // If subdirectories is enabled, they will have suffix '/'. 78 func StatDir(rootPath string, includeDir ...bool) ([]string, error) { 79 if !IsDir(rootPath) { 80 return nil, errors.New("not a directory or does not exist: " + rootPath) 81 } 82 83 isIncludeDir := false 84 if len(includeDir) >= 1 { 85 isIncludeDir = includeDir[0] 86 } 87 return statDir(rootPath, "", isIncludeDir, false) 88 } 89 90 // GetAllSubDirs returns all subdirectories of given root path. 91 // Slice does not include given path itself. 92 func GetAllSubDirs(rootPath string) ([]string, error) { 93 if !IsDir(rootPath) { 94 return nil, errors.New("not a directory or does not exist: " + rootPath) 95 } 96 return statDir(rootPath, "", true, true) 97 } 98 99 // GetFileListBySuffix returns an ordered list of file paths. 100 // It recognize if given path is a file, and don't do recursive find. 101 func GetFileListBySuffix(dirPath, suffix string) ([]string, error) { 102 if !IsExist(dirPath) { 103 return nil, fmt.Errorf("given path does not exist: %s", dirPath) 104 } else if IsFile(dirPath) { 105 return []string{dirPath}, nil 106 } 107 108 // Given path is a directory. 109 dir, err := os.Open(dirPath) 110 if err != nil { 111 return nil, err 112 } 113 114 fis, err := dir.Readdir(0) 115 if err != nil { 116 return nil, err 117 } 118 119 files := make([]string, 0, len(fis)) 120 for _, fi := range fis { 121 if strings.HasSuffix(fi.Name(), suffix) { 122 files = append(files, path.Join(dirPath, fi.Name())) 123 } 124 } 125 126 return files, nil 127 } 128 129 // CopyDir copy files recursively from source to target directory. 130 // 131 // The filter accepts a function that process the path info. 132 // and should return true for need to filter. 133 // 134 // It returns error when error occurs in underlying functions. 135 func CopyDir(srcPath, destPath string, filters ...func(filePath string) bool) error { 136 // Check if target directory exists. 137 if IsExist(destPath) { 138 return errors.New("file or directory alreay exists: " + destPath) 139 } 140 141 err := os.MkdirAll(destPath, os.ModePerm) 142 if err != nil { 143 return err 144 } 145 146 // Gather directory info. 147 infos, err := StatDir(srcPath, true) 148 if err != nil { 149 return err 150 } 151 152 var filter func(filePath string) bool 153 if len(filters) > 0 { 154 filter = filters[0] 155 } 156 157 for _, info := range infos { 158 if filter != nil && filter(info) { 159 continue 160 } 161 162 curPath := path.Join(destPath, info) 163 if strings.HasSuffix(info, "/") { 164 err = os.MkdirAll(curPath, os.ModePerm) 165 } else { 166 err = Copy(path.Join(srcPath, info), curPath) 167 } 168 if err != nil { 169 return err 170 } 171 } 172 return nil 173 }