You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
naza/pkg/filebatch/filebatch.go

132 lines
3.1 KiB
Go

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

// Copyright 2019, Chef. All rights reserved.
// https://github.com/q191201771/naza
//
// Use of this source code is governed by a MIT-style license
// that can be found in the License file.
//
// Author: Chef (191201771@qq.com)
package filebatch
import (
"bytes"
"errors"
"io/ioutil"
"os"
"path/filepath"
"strings"
)
// @param path 带路径的文件名
// @param info 文件的 os.FileInfo 信息
// @param content 文件内容
// @return 返回nil或者content原始内容则不修改文件内容返回其他内容则会覆盖重写文件
type WalkFunc func(path string, info os.FileInfo, content []byte, err error) []byte
// 遍历访问指定文件夹下的文件
// @param root 需要遍历访问的文件夹
// @param recursive 是否递归访问子文件夹
// @param suffix 指定文件名后缀进行过滤,如果为"",则不过滤
func Walk(root string, recursive bool, suffix string, walkFn WalkFunc) error {
err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
if err != nil {
walkFn(path, info, nil, err)
return nil
}
if !recursive && info.IsDir() && path != root {
return filepath.SkipDir
}
if info.IsDir() {
return nil
}
if suffix != "" && !strings.HasSuffix(info.Name(), suffix) {
return nil
}
content, err := ioutil.ReadFile(path)
if err != nil {
walkFn(path, info, content, err)
return nil
}
newContent := walkFn(path, info, content, nil)
if newContent != nil && bytes.Compare(content, newContent) != 0 {
if err = ioutil.WriteFile(path, newContent, 0755); err != nil {
return err
}
}
return nil
})
return err
}
// 文件尾部添加内容
func AddTailContent(content []byte, tail []byte) []byte {
if !bytes.HasSuffix(content, []byte{'\n'}) {
content = append(content, '\n')
}
return append(content, tail...)
}
// 文件头部添加内容
func AddHeadContent(content []byte, head []byte) []byte {
if !bytes.HasSuffix(head, []byte{'\n'}) {
head = append(head, '\n')
}
return append(head, content...)
}
// 行号范围
// 1表示首行-1表示最后一行
type LineRange struct {
From int
To int
}
var ErrLineRange = errors.New("naza.filebatch: line range error")
func calcLineRange(len int, lr LineRange) (LineRange, error) {
// 换算成从0开始的下标
if lr.From < 0 {
lr.From = len + lr.From
} else if lr.From > 0 {
lr.From = lr.From - 1
} else {
return lr, ErrLineRange
}
if lr.To < 0 {
lr.To = len + lr.To
} else if lr.To > 0 {
lr.To = lr.To - 1
} else {
return lr, ErrLineRange
}
// 排序交换
if lr.From > lr.To {
lr.From, lr.To = lr.To, lr.From
}
if lr.From < 0 || lr.From >= len || lr.To < 0 || lr.To >= len {
return lr, ErrLineRange
}
return lr, nil
}
func DeleteLines(content []byte, lr LineRange) ([]byte, error) {
lines := bytes.Split(content, []byte{'\n'})
length := len(lines)
nlr, err := calcLineRange(length, lr)
if err != nil {
return content, err
}
var nlines [][]byte
if nlr.From > 0 {
nlines = append(nlines, lines[:nlr.From]...)
}
if nlr.To < length-1 {
nlines = append(nlines, lines[nlr.To+1:]...)
}
return bytes.Join(nlines, []byte{'\n'}), nil
}