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  }