Skip to content

Commit cda8125

Browse files
committed
feat(sync): 改进文件同步功能
- 使用 doublestar 库实现更灵活的路径匹配 - 优化文件遍历逻辑,支持复杂的包含和排除规则 - 添加日志输出,提高程序可读性和调试方便性 - 重构代码,提高可维护性
1 parent 6a3179a commit cda8125

3 files changed

Lines changed: 90 additions & 17 deletions

File tree

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ require (
88
)
99

1010
require (
11+
github.com/bmatcuk/doublestar/v4 v4.7.1 // indirect
1112
github.com/google/uuid v1.4.0 // indirect
1213
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
1314
github.com/robfig/cron/v3 v3.0.1 // indirect

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
github.com/bmatcuk/doublestar/v4 v4.7.1 h1:fdDeAqgT47acgwd9bd9HxJRDmc9UAmPpc+2m0CXv75Q=
2+
github.com/bmatcuk/doublestar/v4 v4.7.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
13
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
24
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
35
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=

main.go

Lines changed: 87 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313

1414
"runtime"
1515

16+
"github.com/bmatcuk/doublestar/v4"
1617
"github.com/go-co-op/gocron"
1718
"github.com/sevlyar/go-daemon"
1819
"gopkg.in/yaml.v2"
@@ -385,30 +386,67 @@ func (gs *GitSync) syncFiles(job *Job) error {
385386
return err
386387
}
387388

389+
// Normalize source and repo paths
390+
sourcePath := filepath.ToSlash(job.SourcePath)
388391
repoPath := job.GetRepoPath()
389-
gs.logger.Printf("DEBUG: Syncing files from %s to %s\n", job.SourcePath, repoPath)
390392

391-
return filepath.Walk(job.SourcePath, func(path string, info os.FileInfo, err error) error {
393+
// Get absolute path of working directory
394+
workDir, err := os.Getwd()
395+
if err != nil {
396+
return fmt.Errorf("failed to get working directory: %v", err)
397+
}
398+
399+
// Normalize matching pattern
400+
pattern := normalizeSourcePath(sourcePath)
401+
gs.logger.Printf("DEBUG: Using pattern: %s\n", pattern)
402+
403+
// Use filepath.Walk to traverse directory
404+
var matches []string
405+
err = filepath.Walk(filepath.Join(workDir, filepath.Dir(pattern)), func(path string, info os.FileInfo, err error) error {
392406
if err != nil {
393-
return err
407+
gs.logger.Printf("WARNING: Failed to access path %s: %v\n", path, err)
408+
return nil
394409
}
395410

396-
// 跳过目录
397-
if info.IsDir() {
411+
// Convert to relative path
412+
relPath, err := filepath.Rel(workDir, path)
413+
if err != nil {
414+
gs.logger.Printf("WARNING: Cannot get relative path for %s: %v\n", path, err)
398415
return nil
399416
}
400417

401-
// 获取相对路径
402-
relPath, err := filepath.Rel(job.SourcePath, path)
418+
// Convert to forward slash path for matching
419+
relPath = filepath.ToSlash(relPath)
420+
421+
// Check if matches pattern
422+
matched, err := doublestar.Match(pattern, relPath)
403423
if err != nil {
404-
return err
424+
gs.logger.Printf("WARNING: Pattern matching failed for %s: %v\n", relPath, err)
425+
return nil
405426
}
406427

407-
// 检查文件是否应该被同步
408-
if !gs.shouldSync(relPath, job.Includes, job.Excludes) {
409-
return nil
428+
if matched && !info.IsDir() {
429+
gs.logger.Printf("DEBUG: Found matching file: %s\n", relPath)
430+
matches = append(matches, path)
410431
}
432+
return nil
433+
})
434+
435+
if err != nil {
436+
return fmt.Errorf("failed to traverse directory: %v", err)
437+
}
438+
439+
if len(matches) == 0 {
440+
gs.logger.Printf("WARNING: No matching files found for pattern: %s\n", pattern)
441+
return nil
442+
}
443+
444+
// Process matching files
445+
for _, path := range matches {
446+
relPath, _ := filepath.Rel(workDir, path)
447+
relPath = filepath.ToSlash(relPath)
411448

449+
// Determine destination path
412450
var destPath string
413451
switch {
414452
case job.KeepStructure:
@@ -419,21 +457,30 @@ func (gs *GitSync) syncFiles(job *Job) error {
419457
destPath = filepath.Join(repoPath, filepath.Base(path))
420458
}
421459

460+
// Create destination directory
461+
if err := os.MkdirAll(filepath.Dir(destPath), 0755); err != nil {
462+
gs.logger.Printf("WARNING: Failed to create directory %s: %v\n", filepath.Dir(destPath), err)
463+
continue
464+
}
465+
422466
if err := gs.copyFile(path, destPath); err != nil {
423-
return err
467+
gs.logger.Printf("WARNING: Failed to copy file %s: %v\n", path, err)
468+
continue
424469
}
425470

426-
gs.logger.Printf("Synced file: %s to %s\n", relPath, destPath)
427-
return nil
428-
})
471+
gs.logger.Printf("Successfully synced file: %s to %s\n", relPath, destPath)
472+
}
473+
474+
return nil
429475
}
430476

431477
// shouldSync 检查文件是否应该被同步
432478
func (gs *GitSync) shouldSync(path string, includes, excludes []string) bool {
433479
// 首先检查排除规则
434480
for _, exclude := range excludes {
435-
matched, err := filepath.Match(exclude, path)
481+
matched, err := doublestar.Match(exclude, path)
436482
if err == nil && matched {
483+
gs.logger.Printf("DEBUG: file %s excluded by rule %s\n", path, exclude)
437484
return false
438485
}
439486
}
@@ -445,7 +492,7 @@ func (gs *GitSync) shouldSync(path string, includes, excludes []string) bool {
445492

446493
// 检查包含规则
447494
for _, include := range includes {
448-
matched, err := filepath.Match(include, path)
495+
matched, err := doublestar.Match(include, path)
449496
if err == nil && matched {
450497
return true
451498
}
@@ -739,3 +786,26 @@ func main() {
739786
log.Fatalf("Failed to run GitSync: %v", err)
740787
}
741788
}
789+
790+
// 更新辅助函数来处理路径
791+
func normalizeSourcePath(path string) string {
792+
// Convert backslashes to forward slashes
793+
path = filepath.ToSlash(path)
794+
795+
// Remove leading ./
796+
if strings.HasPrefix(path, "./") {
797+
path = path[2:]
798+
}
799+
800+
// Ensure pattern is correct
801+
if !strings.Contains(path, "*") {
802+
// If no wildcard, add /** to match all files
803+
if strings.HasSuffix(path, "/") {
804+
path = path + "**"
805+
} else {
806+
path = path + "/**"
807+
}
808+
}
809+
810+
return path
811+
}

0 commit comments

Comments
 (0)