fix hako sync
This commit is contained in:
parent
30a510cb17
commit
cd1f23527e
3 changed files with 145 additions and 11 deletions
114
utils.go
114
utils.go
|
@ -1,9 +1,11 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
@ -15,6 +17,14 @@ func runCommand(name string, args ...string) error {
|
|||
return cmd.Run()
|
||||
}
|
||||
|
||||
func runCommandSilent(name string, args ...string) error {
|
||||
cmd := exec.Command(name, args...)
|
||||
fmt.Fprintf(os.Stderr, "+ %s %s\n", name, strings.Join(args, " "))
|
||||
cmd.Stdout = nil
|
||||
cmd.Stderr = nil
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func runCommandOutput(name string, args ...string) (string, error) {
|
||||
cmd := exec.Command(name, args...)
|
||||
fmt.Fprintf(os.Stderr, "+ %s %s\n", name, strings.Join(args, " "))
|
||||
|
@ -24,3 +34,107 @@ func runCommandOutput(name string, args ...string) (string, error) {
|
|||
}
|
||||
return strings.TrimSpace(string(output)), nil
|
||||
}
|
||||
|
||||
// GitIgnore represents a .gitignore parser
|
||||
type GitIgnore struct {
|
||||
patterns []string
|
||||
}
|
||||
|
||||
// NewGitIgnore creates a new GitIgnore parser by reading .gitignore file
|
||||
func NewGitIgnore() (*GitIgnore, error) {
|
||||
gi := &GitIgnore{}
|
||||
|
||||
file, err := os.Open(".gitignore")
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return gi, nil // No .gitignore file is fine
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
scanner := bufio.NewScanner(file)
|
||||
for scanner.Scan() {
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
if line != "" && !strings.HasPrefix(line, "#") {
|
||||
gi.patterns = append(gi.patterns, line)
|
||||
}
|
||||
}
|
||||
|
||||
return gi, scanner.Err()
|
||||
}
|
||||
|
||||
// IsIgnored checks if a file path should be ignored according to .gitignore patterns
|
||||
func (gi *GitIgnore) IsIgnored(path string) bool {
|
||||
for _, pattern := range gi.patterns {
|
||||
if gi.matchPattern(pattern, path) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// matchPattern implements basic gitignore pattern matching
|
||||
func (gi *GitIgnore) matchPattern(pattern, path string) bool {
|
||||
// Handle negation patterns (starting with !)
|
||||
if strings.HasPrefix(pattern, "!") {
|
||||
return false // Negation patterns would require more complex logic
|
||||
}
|
||||
|
||||
// Convert gitignore pattern to filepath.Match compatible pattern
|
||||
// Handle directory patterns (ending with /)
|
||||
if strings.HasSuffix(pattern, "/") {
|
||||
pattern = strings.TrimSuffix(pattern, "/")
|
||||
// Check if any directory component matches
|
||||
parts := strings.Split(path, string(filepath.Separator))
|
||||
for _, part := range parts {
|
||||
if matched, _ := filepath.Match(pattern, part); matched {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Handle patterns with path separators
|
||||
if strings.Contains(pattern, "/") {
|
||||
// Exact path match
|
||||
if matched, _ := filepath.Match(pattern, path); matched {
|
||||
return true
|
||||
}
|
||||
// Check if pattern matches any suffix of the path
|
||||
pathParts := strings.Split(path, string(filepath.Separator))
|
||||
patternParts := strings.Split(pattern, "/")
|
||||
|
||||
if len(patternParts) <= len(pathParts) {
|
||||
for i := 0; i <= len(pathParts)-len(patternParts); i++ {
|
||||
match := true
|
||||
for j, patternPart := range patternParts {
|
||||
if matched, _ := filepath.Match(patternPart, pathParts[i+j]); !matched {
|
||||
match = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if match {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// Simple filename pattern - check against basename and any path component
|
||||
basename := filepath.Base(path)
|
||||
if matched, _ := filepath.Match(pattern, basename); matched {
|
||||
return true
|
||||
}
|
||||
|
||||
// Check if pattern matches any directory component
|
||||
parts := strings.Split(path, string(filepath.Separator))
|
||||
for _, part := range parts {
|
||||
if matched, _ := filepath.Match(pattern, part); matched {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue