code: 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
  }
docs: // 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.