podman

Форк
0
329 строк · 7.2 Кб
1
// Copyright ©2015 Steve Francia <spf@spf13.com>
2
// Portions Copyright ©2015 The Hugo Authors
3
// Portions Copyright 2016-present Bjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
4
//
5
// Licensed under the Apache License, Version 2.0 (the "License");
6
// you may not use this file except in compliance with the License.
7
// You may obtain a copy of the License at
8
//
9
//     http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing, software
12
// distributed under the License is distributed on an "AS IS" BASIS,
13
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
// See the License for the specific language governing permissions and
15
// limitations under the License.
16

17
package afero
18

19
import (
20
	"bytes"
21
	"fmt"
22
	"io"
23
	"os"
24
	"path/filepath"
25
	"strings"
26
	"unicode"
27

28
	"golang.org/x/text/runes"
29
	"golang.org/x/text/transform"
30
	"golang.org/x/text/unicode/norm"
31
)
32

33
// Filepath separator defined by os.Separator.
34
const FilePathSeparator = string(filepath.Separator)
35

36
// Takes a reader and a path and writes the content
37
func (a Afero) WriteReader(path string, r io.Reader) (err error) {
38
	return WriteReader(a.Fs, path, r)
39
}
40

41
func WriteReader(fs Fs, path string, r io.Reader) (err error) {
42
	dir, _ := filepath.Split(path)
43
	ospath := filepath.FromSlash(dir)
44

45
	if ospath != "" {
46
		err = fs.MkdirAll(ospath, 0o777) // rwx, rw, r
47
		if err != nil {
48
			if err != os.ErrExist {
49
				return err
50
			}
51
		}
52
	}
53

54
	file, err := fs.Create(path)
55
	if err != nil {
56
		return
57
	}
58
	defer file.Close()
59

60
	_, err = io.Copy(file, r)
61
	return
62
}
63

64
// Same as WriteReader but checks to see if file/directory already exists.
65
func (a Afero) SafeWriteReader(path string, r io.Reader) (err error) {
66
	return SafeWriteReader(a.Fs, path, r)
67
}
68

69
func SafeWriteReader(fs Fs, path string, r io.Reader) (err error) {
70
	dir, _ := filepath.Split(path)
71
	ospath := filepath.FromSlash(dir)
72

73
	if ospath != "" {
74
		err = fs.MkdirAll(ospath, 0o777) // rwx, rw, r
75
		if err != nil {
76
			return
77
		}
78
	}
79

80
	exists, err := Exists(fs, path)
81
	if err != nil {
82
		return
83
	}
84
	if exists {
85
		return fmt.Errorf("%v already exists", path)
86
	}
87

88
	file, err := fs.Create(path)
89
	if err != nil {
90
		return
91
	}
92
	defer file.Close()
93

94
	_, err = io.Copy(file, r)
95
	return
96
}
97

98
func (a Afero) GetTempDir(subPath string) string {
99
	return GetTempDir(a.Fs, subPath)
100
}
101

102
// GetTempDir returns the default temp directory with trailing slash
103
// if subPath is not empty then it will be created recursively with mode 777 rwx rwx rwx
104
func GetTempDir(fs Fs, subPath string) string {
105
	addSlash := func(p string) string {
106
		if FilePathSeparator != p[len(p)-1:] {
107
			p = p + FilePathSeparator
108
		}
109
		return p
110
	}
111
	dir := addSlash(os.TempDir())
112

113
	if subPath != "" {
114
		// preserve windows backslash :-(
115
		if FilePathSeparator == "\\" {
116
			subPath = strings.Replace(subPath, "\\", "____", -1)
117
		}
118
		dir = dir + UnicodeSanitize((subPath))
119
		if FilePathSeparator == "\\" {
120
			dir = strings.Replace(dir, "____", "\\", -1)
121
		}
122

123
		if exists, _ := Exists(fs, dir); exists {
124
			return addSlash(dir)
125
		}
126

127
		err := fs.MkdirAll(dir, 0o777)
128
		if err != nil {
129
			panic(err)
130
		}
131
		dir = addSlash(dir)
132
	}
133
	return dir
134
}
135

136
// Rewrite string to remove non-standard path characters
137
func UnicodeSanitize(s string) string {
138
	source := []rune(s)
139
	target := make([]rune, 0, len(source))
140

141
	for _, r := range source {
142
		if unicode.IsLetter(r) ||
143
			unicode.IsDigit(r) ||
144
			unicode.IsMark(r) ||
145
			r == '.' ||
146
			r == '/' ||
147
			r == '\\' ||
148
			r == '_' ||
149
			r == '-' ||
150
			r == '%' ||
151
			r == ' ' ||
152
			r == '#' {
153
			target = append(target, r)
154
		}
155
	}
156

157
	return string(target)
158
}
159

160
// Transform characters with accents into plain forms.
161
func NeuterAccents(s string) string {
162
	t := transform.Chain(norm.NFD, runes.Remove(runes.In(unicode.Mn)), norm.NFC)
163
	result, _, _ := transform.String(t, string(s))
164

165
	return result
166
}
167

168
func (a Afero) FileContainsBytes(filename string, subslice []byte) (bool, error) {
169
	return FileContainsBytes(a.Fs, filename, subslice)
170
}
171

172
// Check if a file contains a specified byte slice.
173
func FileContainsBytes(fs Fs, filename string, subslice []byte) (bool, error) {
174
	f, err := fs.Open(filename)
175
	if err != nil {
176
		return false, err
177
	}
178
	defer f.Close()
179

180
	return readerContainsAny(f, subslice), nil
181
}
182

183
func (a Afero) FileContainsAnyBytes(filename string, subslices [][]byte) (bool, error) {
184
	return FileContainsAnyBytes(a.Fs, filename, subslices)
185
}
186

187
// Check if a file contains any of the specified byte slices.
188
func FileContainsAnyBytes(fs Fs, filename string, subslices [][]byte) (bool, error) {
189
	f, err := fs.Open(filename)
190
	if err != nil {
191
		return false, err
192
	}
193
	defer f.Close()
194

195
	return readerContainsAny(f, subslices...), nil
196
}
197

198
// readerContains reports whether any of the subslices is within r.
199
func readerContainsAny(r io.Reader, subslices ...[]byte) bool {
200
	if r == nil || len(subslices) == 0 {
201
		return false
202
	}
203

204
	largestSlice := 0
205

206
	for _, sl := range subslices {
207
		if len(sl) > largestSlice {
208
			largestSlice = len(sl)
209
		}
210
	}
211

212
	if largestSlice == 0 {
213
		return false
214
	}
215

216
	bufflen := largestSlice * 4
217
	halflen := bufflen / 2
218
	buff := make([]byte, bufflen)
219
	var err error
220
	var n, i int
221

222
	for {
223
		i++
224
		if i == 1 {
225
			n, err = io.ReadAtLeast(r, buff[:halflen], halflen)
226
		} else {
227
			if i != 2 {
228
				// shift left to catch overlapping matches
229
				copy(buff[:], buff[halflen:])
230
			}
231
			n, err = io.ReadAtLeast(r, buff[halflen:], halflen)
232
		}
233

234
		if n > 0 {
235
			for _, sl := range subslices {
236
				if bytes.Contains(buff, sl) {
237
					return true
238
				}
239
			}
240
		}
241

242
		if err != nil {
243
			break
244
		}
245
	}
246
	return false
247
}
248

249
func (a Afero) DirExists(path string) (bool, error) {
250
	return DirExists(a.Fs, path)
251
}
252

253
// DirExists checks if a path exists and is a directory.
254
func DirExists(fs Fs, path string) (bool, error) {
255
	fi, err := fs.Stat(path)
256
	if err == nil && fi.IsDir() {
257
		return true, nil
258
	}
259
	if os.IsNotExist(err) {
260
		return false, nil
261
	}
262
	return false, err
263
}
264

265
func (a Afero) IsDir(path string) (bool, error) {
266
	return IsDir(a.Fs, path)
267
}
268

269
// IsDir checks if a given path is a directory.
270
func IsDir(fs Fs, path string) (bool, error) {
271
	fi, err := fs.Stat(path)
272
	if err != nil {
273
		return false, err
274
	}
275
	return fi.IsDir(), nil
276
}
277

278
func (a Afero) IsEmpty(path string) (bool, error) {
279
	return IsEmpty(a.Fs, path)
280
}
281

282
// IsEmpty checks if a given file or directory is empty.
283
func IsEmpty(fs Fs, path string) (bool, error) {
284
	if b, _ := Exists(fs, path); !b {
285
		return false, fmt.Errorf("%q path does not exist", path)
286
	}
287
	fi, err := fs.Stat(path)
288
	if err != nil {
289
		return false, err
290
	}
291
	if fi.IsDir() {
292
		f, err := fs.Open(path)
293
		if err != nil {
294
			return false, err
295
		}
296
		defer f.Close()
297
		list, err := f.Readdir(-1)
298
		if err != nil {
299
			return false, err
300
		}
301
		return len(list) == 0, nil
302
	}
303
	return fi.Size() == 0, nil
304
}
305

306
func (a Afero) Exists(path string) (bool, error) {
307
	return Exists(a.Fs, path)
308
}
309

310
// Check if a file or directory exists.
311
func Exists(fs Fs, path string) (bool, error) {
312
	_, err := fs.Stat(path)
313
	if err == nil {
314
		return true, nil
315
	}
316
	if os.IsNotExist(err) {
317
		return false, nil
318
	}
319
	return false, err
320
}
321

322
func FullBaseFsPath(basePathFs *BasePathFs, relativePath string) string {
323
	combinedPath := filepath.Join(basePathFs.path, relativePath)
324
	if parent, ok := basePathFs.source.(*BasePathFs); ok {
325
		return FullBaseFsPath(parent, combinedPath)
326
	}
327

328
	return combinedPath
329
}
330

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.