| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173 | // Copyright 2013 com authors//// Licensed under the Apache License, Version 2.0 (the "License"): you may// not use this file except in compliance with the License. You may obtain// a copy of the License at////     http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the// License for the specific language governing permissions and limitations// under the License.package comimport (	"errors"	"fmt"	"os"	"path"	"strings")// IsDir returns true if given path is a directory,// or returns false when it's a file or does not exist.func IsDir(dir string) bool {	f, e := os.Stat(dir)	if e != nil {		return false	}	return f.IsDir()}func statDir(dirPath, recPath string, includeDir, isDirOnly bool) ([]string, error) {	dir, err := os.Open(dirPath)	if err != nil {		return nil, err	}	defer dir.Close()	fis, err := dir.Readdir(0)	if err != nil {		return nil, err	}	statList := make([]string, 0)	for _, fi := range fis {		if strings.Contains(fi.Name(), ".DS_Store") {			continue		}		relPath := path.Join(recPath, fi.Name())		curPath := path.Join(dirPath, fi.Name())		if fi.IsDir() {			if includeDir {				statList = append(statList, relPath+"/")			}			s, err := statDir(curPath, relPath, includeDir, isDirOnly)			if err != nil {				return nil, err			}			statList = append(statList, s...)		} else if !isDirOnly {			statList = append(statList, relPath)		}	}	return statList, nil}// StatDir gathers information of given directory by depth-first.// It returns slice of file list and includes subdirectories if enabled;// it returns error and nil slice when error occurs in underlying functions,// or given path is not a directory or does not exist.//// Slice does not include given path itself.// If subdirectories is enabled, they will have suffix '/'.func StatDir(rootPath string, includeDir ...bool) ([]string, error) {	if !IsDir(rootPath) {		return nil, errors.New("not a directory or does not exist: " + rootPath)	}	isIncludeDir := false	if len(includeDir) >= 1 {		isIncludeDir = includeDir[0]	}	return statDir(rootPath, "", isIncludeDir, false)}// GetAllSubDirs returns all subdirectories of given root path.// Slice does not include given path itself.func GetAllSubDirs(rootPath string) ([]string, error) {	if !IsDir(rootPath) {		return nil, errors.New("not a directory or does not exist: " + rootPath)	}	return statDir(rootPath, "", true, true)}// GetFileListBySuffix returns an ordered list of file paths.// It recognize if given path is a file, and don't do recursive find.func GetFileListBySuffix(dirPath, suffix string) ([]string, error) {	if !IsExist(dirPath) {		return nil, fmt.Errorf("given path does not exist: %s", dirPath)	} else if IsFile(dirPath) {		return []string{dirPath}, nil	}	// Given path is a directory.	dir, err := os.Open(dirPath)	if err != nil {		return nil, err	}	fis, err := dir.Readdir(0)	if err != nil {		return nil, err	}	files := make([]string, 0, len(fis))	for _, fi := range fis {		if strings.HasSuffix(fi.Name(), suffix) {			files = append(files, path.Join(dirPath, fi.Name()))		}	}	return files, nil}// CopyDir copy files recursively from source to target directory.//// The filter accepts a function that process the path info.// and should return true for need to filter.//// It returns error when error occurs in underlying functions.func CopyDir(srcPath, destPath string, filters ...func(filePath string) bool) error {	// Check if target directory exists.	if IsExist(destPath) {		return errors.New("file or directory alreay exists: " + destPath)	}	err := os.MkdirAll(destPath, os.ModePerm)	if err != nil {		return err	}	// Gather directory info.	infos, err := StatDir(srcPath, true)	if err != nil {		return err	}	var filter func(filePath string) bool	if len(filters) > 0 {		filter = filters[0]	}	for _, info := range infos {		if filter != nil && filter(info) {			continue		}		curPath := path.Join(destPath, info)		if strings.HasSuffix(info, "/") {			err = os.MkdirAll(curPath, os.ModePerm)		} else {			err = Copy(path.Join(srcPath, info), curPath)		}		if err != nil {			return err		}	}	return nil}
 |