diff --git a/.gitignore b/.gitignore index 64d9329..e707320 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,4 @@ profile*.pdf /TODO.md /pkg/tag -/pkg/taskpool/spinlock.go +/demo/samefile diff --git a/build.sh b/build.sh index 3f29df7..0c15cd7 100755 --- a/build.sh +++ b/build.sh @@ -27,5 +27,6 @@ cd ${ROOT_DIR}/demo/add_blog_license && go build -ldflags "$LDFlags" -o ${ROOT_D cd ${ROOT_DIR}/demo/add_go_license && go build -ldflags "$LDFlags" -o ${ROOT_DIR}/bin/add_go_license && cd ${ROOT_DIR}/demo/taskpool && go build -ldflags "$LDFlags" -o ${ROOT_DIR}/bin/taskpool && cd ${ROOT_DIR}/demo/bufferpool && go build -ldflags "$LDFlags" -o ${ROOT_DIR}/bin/bufferpool && +cd ${ROOT_DIR}/demo/samefile && go build -ldflags "$LDFlags" -o ${ROOT_DIR}/bin/samefile && ls -lrt ${ROOT_DIR}/bin && echo 'build done.' diff --git a/demo/add_blog_license/main.go b/demo/add_blog_license/main.go index c287f4a..41d189a 100644 --- a/demo/add_blog_license/main.go +++ b/demo/add_blog_license/main.go @@ -32,7 +32,11 @@ func main() { skipCount int modCount int ) - err := filebatch.Walk(dir, true, ".md", func(path string, info os.FileInfo, content []byte) []byte { + err2 := filebatch.Walk(dir, true, ".md", func(path string, info os.FileInfo, content []byte, err error) []byte { + if err != nil { + nazalog.Warnf("read file failed. file=%s, err=%+v", path, err) + return nil + } lines := bytes.Split(content, []byte{'\n'}) if bytes.Index(lines[len(lines)-1], []byte("声明")) != -1 || bytes.Index(lines[len(lines)-2], []byte("声明")) != -1 { @@ -53,7 +57,7 @@ func main() { license := fmt.Sprintf(licenseTmpl, abbrlink, abbrlink) return filebatch.AddTailContent(content, []byte(license)) }) - nazalog.FatalIfErrorNotNil(err) + nazalog.FatalIfErrorNotNil(err2) nazalog.Infof("count. mod=%d, skip=%d", modCount, skipCount) } diff --git a/demo/add_go_license/main.go b/demo/add_go_license/main.go index 7ce4c0b..d972338 100644 --- a/demo/add_go_license/main.go +++ b/demo/add_go_license/main.go @@ -43,7 +43,11 @@ func main() { skipCount int modCount int ) - err := filebatch.Walk(dir, true, ".go", func(path string, info os.FileInfo, content []byte) []byte { + err2 := filebatch.Walk(dir, true, ".go", func(path string, info os.FileInfo, content []byte, err error) []byte { + if err != nil { + nazalog.Warnf("read file failed. file=%s, err=%+v", path, err) + return nil + } lines := bytes.Split(content, []byte{'\n'}) if bytes.Index(lines[0], []byte("Copyright")) != -1 { skipCount++ @@ -55,7 +59,7 @@ func main() { modCount++ return filebatch.AddHeadContent(content, []byte(license)) }) - nazalog.FatalIfErrorNotNil(err) + nazalog.FatalIfErrorNotNil(err2) nazalog.Infof("count. mod=%d, skip=%d", modCount, skipCount) } diff --git a/pkg/filebatch/filebatch.go b/pkg/filebatch/filebatch.go index e85c936..f8cffc8 100644 --- a/pkg/filebatch/filebatch.go +++ b/pkg/filebatch/filebatch.go @@ -21,7 +21,7 @@ import ( // @param info 文件的 os.FileInfo 信息 // @param content 文件内容 // @return 返回nil或者content原始内容,则不修改文件内容,返回其他内容,则会覆盖重写文件 -type WalkFunc func(path string, info os.FileInfo, content []byte) []byte +type WalkFunc func(path string, info os.FileInfo, content []byte, err error) []byte // 遍历访问指定文件夹下的文件 // @param root 需要遍历访问的文件夹 @@ -30,7 +30,8 @@ type WalkFunc func(path string, info os.FileInfo, content []byte) []byte 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 { - return err + walkFn(path, info, nil, err) + return nil } if !recursive && info.IsDir() && path != root { return filepath.SkipDir @@ -44,9 +45,10 @@ func Walk(root string, recursive bool, suffix string, walkFn WalkFunc) error { content, err := ioutil.ReadFile(path) if err != nil { - return err + walkFn(path, info, content, err) + return nil } - newContent := walkFn(path, info, content) + 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 diff --git a/pkg/filebatch/filebatch_test.go b/pkg/filebatch/filebatch_test.go index 5b295e4..7991a2b 100644 --- a/pkg/filebatch/filebatch_test.go +++ b/pkg/filebatch/filebatch_test.go @@ -88,7 +88,7 @@ func testWalk(t *testing.T, recursive bool, suffix string) { assert.Equal(t, nil, err) defer os.RemoveAll(root) - err = Walk(root, recursive, suffix, func(path string, info os.FileInfo, content []byte) []byte { + err2 := Walk(root, recursive, suffix, func(path string, info os.FileInfo, content []byte, err error) []byte { nazalog.Debugf("%+v %+v %s", path, info.Name(), string(content)) v := filenameToContent[path] @@ -97,7 +97,7 @@ func testWalk(t *testing.T, recursive bool, suffix string) { return content }) - assert.Equal(t, nil, err) + assert.Equal(t, nil, err2) } func TestWalk(t *testing.T) { @@ -122,7 +122,7 @@ func TestAddContent(t *testing.T) { assert.Equal(t, nil, err) defer os.RemoveAll(root) - err = Walk(root, true, ".txt", func(path string, info os.FileInfo, content []byte) []byte { + err2 := Walk(root, true, ".txt", func(path string, info os.FileInfo, content []byte, err error) []byte { lines := bytes.Split(content, []byte{'\n'}) nazalog.Debugf("%+v %d", path, len(lines)) @@ -132,12 +132,13 @@ func TestAddContent(t *testing.T) { return AddHeadContent(AddTailContent(content, []byte(tail)), []byte(head)) }) - assert.Equal(t, nil, err) + assert.Equal(t, nil, err2) - err = Walk(root, true, "", func(path string, info os.FileInfo, content []byte) []byte { + err2 = Walk(root, true, "", func(path string, info os.FileInfo, content []byte, err error) []byte { nazalog.Debugf("%+v %+v %s", path, info.Name(), string(content)) return nil }) + assert.Equal(t, nil, err2) } func TestDeleteLines(t *testing.T) { diff --git a/pkg/nazalog/log.go b/pkg/nazalog/log.go index 7ec22e9..ef9f86d 100644 --- a/pkg/nazalog/log.go +++ b/pkg/nazalog/log.go @@ -184,24 +184,6 @@ func (l *logger) Out(level Level, calldepth int, s string) { } } -// @NOTICE 该函数拷贝自 Go 标准库 -// Cheap integer to fixed-width decimal ASCII. Give a negative width to avoid zero-padding. -func itoa(buf *bytes.Buffer, i int, wid int) { - // Assemble decimal in reverse order. - var b [20]byte - bp := len(b) - 1 - for i >= 10 || wid > 1 { - wid-- - q := i / 10 - b[bp] = byte('0' + i - q*10) - bp-- - i = q - } - // i < 10 - b[bp] = byte('0' + i) - buf.Write(b[bp:]) -} - func writeTime(buf *bytes.Buffer, t time.Time) { year, month, day := t.Date() itoa(buf, year, 4) @@ -243,3 +225,25 @@ func writeShortFile(buf *bytes.Buffer, calldepth int) { buf.WriteByte(':') itoa(buf, line, -1) } + +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// @NOTICE 该函数拷贝自 Go 标准库 /src/log/log.go: func itoa(buf *[]byte, i int, wid int) +// Cheap integer to fixed-width decimal ASCII. Give a negative width to avoid zero-padding. +func itoa(buf *bytes.Buffer, i int, wid int) { + // Assemble decimal in reverse order. + var b [20]byte + bp := len(b) - 1 + for i >= 10 || wid > 1 { + wid-- + q := i / 10 + b[bp] = byte('0' + i - q*10) + bp-- + i = q + } + // i < 10 + b[bp] = byte('0' + i) + buf.Write(b[bp:]) +}