github.com/mysteriumnetwork/node@v0.0.0-20240516044423-365054f76801/utils/fileutil/fileutil.go (about) 1 /* 2 * Copyright (C) 2020 The "MysteriumNetwork/node" Authors. 3 * 4 * This program is free software: you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 18 // Copyright 2018 The Prometheus Authors 19 // Licensed under the Apache License, Version 2.0 (the "License"); 20 // you may not use this file except in compliance with the License. 21 // You may obtain a copy of the License at 22 // 23 // http://www.apache.org/licenses/LICENSE-2.0 24 // 25 // Unless required by applicable law or agreed to in writing, software 26 // distributed under the License is distributed on an "AS IS" BASIS, 27 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 28 // See the License for the specific language governing permissions and 29 // limitations under the License. 30 31 // Package fileutil provides utility methods used when dealing with the filesystem in tsdb. 32 // It is largely copied from github.com/coreos/etcd/pkg/fileutil to avoid the 33 // dependency chain it brings with it. 34 // Please check github.com/coreos/etcd for licensing information. 35 36 package fileutil 37 38 import ( 39 "os" 40 "path/filepath" 41 "sort" 42 "strings" 43 ) 44 45 // CopyDirs copies all directories, subdirectories and files recursively including the empty folders. 46 // Source and destination must be full paths. 47 func CopyDirs(src, dest string) error { 48 if err := os.MkdirAll(dest, 0777); err != nil { 49 return err 50 } 51 files, err := readDirs(src) 52 if err != nil { 53 return err 54 } 55 56 for _, f := range files { 57 dp := filepath.Join(dest, f) 58 sp := filepath.Join(src, f) 59 60 stat, err := os.Stat(sp) 61 if err != nil { 62 return err 63 } 64 65 // Empty directories are also created. 66 if stat.IsDir() { 67 if err := os.MkdirAll(dp, 0777); err != nil { 68 return err 69 } 70 continue 71 } 72 73 if err := copyFile(sp, dp); err != nil { 74 return err 75 } 76 } 77 return nil 78 } 79 80 // copyFile copies a file from `src` to `dest`. 81 // It tries to also copy it with the same permissions, 82 // if thats not possible 0644 is used. 83 func copyFile(src, dest string) error { 84 data, err := os.ReadFile(src) 85 if err != nil { 86 return err 87 } 88 89 perm := os.FileMode(0644) 90 if info, err := os.Stat(src); err == nil { 91 perm = info.Mode().Perm() 92 } 93 94 err = os.WriteFile(dest, data, perm) 95 if err != nil { 96 return err 97 } 98 return nil 99 } 100 101 // readDirs reads the source directory recursively and 102 // returns relative paths to all files and empty directories. 103 func readDirs(src string) ([]string, error) { 104 var files []string 105 106 err := filepath.Walk(src, func(path string, f os.FileInfo, err error) error { 107 relativePath := strings.TrimPrefix(path, src) 108 if len(relativePath) > 0 { 109 files = append(files, relativePath) 110 } 111 return nil 112 }) 113 if err != nil { 114 return nil, err 115 } 116 return files, nil 117 } 118 119 // ReadDir returns the filenames in the given directory in sorted order. 120 func ReadDir(dirpath string) ([]string, error) { 121 dir, err := os.Open(dirpath) 122 if err != nil { 123 return nil, err 124 } 125 defer dir.Close() 126 names, err := dir.Readdirnames(-1) 127 if err != nil { 128 return nil, err 129 } 130 sort.Strings(names) 131 return names, nil 132 }