github.com/devwanda/aphelion-staking@v0.33.9/cmd/tendermint/commands/debug/io.go (about)

     1  package debug
     2  
     3  import (
     4  	"archive/zip"
     5  	"encoding/json"
     6  	"io"
     7  	"io/ioutil"
     8  	"os"
     9  	"path"
    10  	"path/filepath"
    11  	"strings"
    12  
    13  	"github.com/pkg/errors"
    14  )
    15  
    16  // zipDir zips all the contents found in src, including both files and
    17  // directories, into a destination file dest. It returns an error upon failure.
    18  // It assumes src is a directory.
    19  func zipDir(src, dest string) error {
    20  	zipFile, err := os.Create(dest)
    21  	if err != nil {
    22  		return err
    23  	}
    24  	defer zipFile.Close()
    25  
    26  	zipWriter := zip.NewWriter(zipFile)
    27  	defer zipWriter.Close()
    28  
    29  	dirName := filepath.Base(dest)
    30  	baseDir := strings.TrimSuffix(dirName, filepath.Ext(dirName))
    31  
    32  	filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
    33  		if err != nil {
    34  			return err
    35  		}
    36  
    37  		header, err := zip.FileInfoHeader(info)
    38  		if err != nil {
    39  			return err
    40  		}
    41  
    42  		// Each execution of this utility on a Tendermint process will result in a
    43  		// unique file.
    44  		header.Name = filepath.Join(baseDir, strings.TrimPrefix(path, src))
    45  
    46  		// Handle cases where the content to be zipped is a file or a directory,
    47  		// where a directory must have a '/' suffix.
    48  		if info.IsDir() {
    49  			header.Name += "/"
    50  		} else {
    51  			header.Method = zip.Deflate
    52  		}
    53  
    54  		headerWriter, err := zipWriter.CreateHeader(header)
    55  		if err != nil {
    56  			return err
    57  		}
    58  
    59  		if info.IsDir() {
    60  			return nil
    61  		}
    62  
    63  		file, err := os.Open(path)
    64  		if err != nil {
    65  			return err
    66  		}
    67  		defer file.Close()
    68  
    69  		_, err = io.Copy(headerWriter, file)
    70  		return err
    71  	})
    72  
    73  	return nil
    74  }
    75  
    76  // copyFile copies a file from src to dest and returns an error upon failure. The
    77  // copied file retains the source file's permissions.
    78  func copyFile(src, dest string) error {
    79  	if _, err := os.Stat(src); os.IsNotExist(err) {
    80  		return err
    81  	}
    82  
    83  	srcFile, err := os.Open(src)
    84  	if err != nil {
    85  		return err
    86  	}
    87  	defer srcFile.Close()
    88  
    89  	destFile, err := os.Create(dest)
    90  	if err != nil {
    91  		return err
    92  	}
    93  	defer destFile.Close()
    94  
    95  	if _, err = io.Copy(destFile, srcFile); err != nil {
    96  		return err
    97  	}
    98  
    99  	srcInfo, err := os.Stat(src)
   100  	if err != nil {
   101  		return err
   102  	}
   103  
   104  	return os.Chmod(dest, srcInfo.Mode())
   105  }
   106  
   107  // writeStateToFile pretty JSON encodes an object and writes it to file composed
   108  // of dir and filename. It returns an error upon failure to encode or write to
   109  // file.
   110  func writeStateJSONToFile(state interface{}, dir, filename string) error {
   111  	stateJSON, err := json.MarshalIndent(state, "", "  ")
   112  	if err != nil {
   113  		return errors.Wrap(err, "failed to encode state dump")
   114  	}
   115  
   116  	return ioutil.WriteFile(path.Join(dir, filename), stateJSON, os.ModePerm)
   117  }