github.com/kovansky/hugo@v0.92.3-0.20220224232819-63076e4ff19f/common/hugio/copy.go (about)

     1  // Copyright 2019 The Hugo Authors. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package hugio
    15  
    16  import (
    17  	"io"
    18  	"io/ioutil"
    19  	"os"
    20  	"path/filepath"
    21  
    22  	"github.com/pkg/errors"
    23  
    24  	"github.com/spf13/afero"
    25  )
    26  
    27  // CopyFile copies a file.
    28  func CopyFile(fs afero.Fs, from, to string) error {
    29  	sf, err := fs.Open(from)
    30  	if err != nil {
    31  		return err
    32  	}
    33  	defer sf.Close()
    34  	df, err := fs.Create(to)
    35  	if err != nil {
    36  		return err
    37  	}
    38  	defer df.Close()
    39  	_, err = io.Copy(df, sf)
    40  	if err != nil {
    41  		return err
    42  	}
    43  	si, err := fs.Stat(from)
    44  	if err != nil {
    45  		err = fs.Chmod(to, si.Mode())
    46  
    47  		if err != nil {
    48  			return err
    49  		}
    50  	}
    51  
    52  	return nil
    53  }
    54  
    55  // CopyDir copies a directory.
    56  func CopyDir(fs afero.Fs, from, to string, shouldCopy func(filename string) bool) error {
    57  	fi, err := os.Stat(from)
    58  	if err != nil {
    59  		return err
    60  	}
    61  
    62  	if !fi.IsDir() {
    63  		return errors.Errorf("%q is not a directory", from)
    64  	}
    65  
    66  	err = fs.MkdirAll(to, 0777) // before umask
    67  	if err != nil {
    68  		return err
    69  	}
    70  
    71  	entries, _ := ioutil.ReadDir(from)
    72  	for _, entry := range entries {
    73  		fromFilename := filepath.Join(from, entry.Name())
    74  		toFilename := filepath.Join(to, entry.Name())
    75  		if entry.IsDir() {
    76  			if shouldCopy != nil && !shouldCopy(fromFilename) {
    77  				continue
    78  			}
    79  			if err := CopyDir(fs, fromFilename, toFilename, shouldCopy); err != nil {
    80  				return err
    81  			}
    82  		} else {
    83  			if err := CopyFile(fs, fromFilename, toFilename); err != nil {
    84  				return err
    85  			}
    86  		}
    87  
    88  	}
    89  
    90  	return nil
    91  }