Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

implement .goitignore #127

Merged
merged 4 commits into from
Jun 17, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions cmd/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,7 @@ var addCmd = &cobra.Command{
// check if the arg is the target of excluding path
cleanedArg := filepath.Clean(arg)
cleanedArg = strings.ReplaceAll(cleanedArg, `\`, "/")
isExcluded := false
for _, excludePath := range client.ExcludePaths {
if excludePath == cleanedArg {
isExcluded = true
}
}
if isExcluded {
if client.Ignore.IsIncluded(cleanedArg) {
continue
}

Expand Down
9 changes: 7 additions & 2 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,17 @@ func init() {
fmt.Println(err)
os.Exit(1)
}
r, err := store.NewRefs(rootGoitPath)
refs, err := store.NewRefs(rootGoitPath)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
client = store.NewClient(config, index, head, r, rootGoitPath)
ignore, err := store.NewIgnore(rootGoitPath)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
client = store.NewClient(config, index, head, refs, ignore, rootGoitPath)

gLogger = log.NewGoitLogger(client.RootGoitPath)

Expand Down
6 changes: 3 additions & 3 deletions internal/store/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@ type Client struct {
Idx *Index
Head *Head
Refs *Refs
Ignore *Ignore
RootGoitPath string
ExcludePaths []string
}

func NewClient(config *Config, index *Index, head *Head, refs *Refs, rootGoitPath string) *Client {
func NewClient(config *Config, index *Index, head *Head, refs *Refs, ignore *Ignore, rootGoitPath string) *Client {
return &Client{
Conf: config,
Idx: index,
Head: head,
Refs: refs,
Ignore: ignore,
RootGoitPath: rootGoitPath,
ExcludePaths: []string{".goit"},
}
}
75 changes: 75 additions & 0 deletions internal/store/ignore.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package store

import (
"bufio"
"fmt"
"os"
"path/filepath"
"regexp"
"strings"
)

var (
directoryRegexp = regexp.MustCompile(`.*\/`)
)

type Ignore struct {
paths []string
}

func NewIgnore(rootGoitPath string) (*Ignore, error) {
i := newIgnore()
if err := i.load(rootGoitPath); err != nil {
return nil, err
}
return i, nil
}

func newIgnore() *Ignore {
return &Ignore{
paths: []string{`\.goit/.*`},
}
}

func (i *Ignore) load(rootGoitPath string) error {
goitignorePath := filepath.Join(filepath.Dir(rootGoitPath), ".goitignore")
if _, err := os.Stat(goitignorePath); os.IsNotExist(err) {
return nil
}
f, err := os.Open(goitignorePath)
if err != nil {
return fmt.Errorf("fail to open %s: %w", goitignorePath, err)
}
defer f.Close()

scanner := bufio.NewScanner(f)
for scanner.Scan() {
text := scanner.Text()
var replacedText string
if directoryRegexp.MatchString(text) {
replacedText = fmt.Sprintf("%s.*", text)
} else {
replacedText = strings.ReplaceAll(text, ".", `\.`)
replacedText = strings.ReplaceAll(replacedText, "*", ".*")
}
i.paths = append(i.paths, replacedText)
}

return nil
}

// return true if the parameter is included in ignore list
func (i *Ignore) IsIncluded(path string) bool {
target := path
info, _ := os.Stat(path)
if info.IsDir() && !directoryRegexp.MatchString(path) {
target = fmt.Sprintf("%s/", path)
}
for _, exFile := range i.paths {
exRegexp := regexp.MustCompile(exFile)
if exRegexp.MatchString(target) {
return true
}
}
return false
}
66 changes: 66 additions & 0 deletions internal/store/ignore_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package store

import (
"os"
"path/filepath"
"reflect"
"testing"
)

func TestNewIgnore(t *testing.T) {
type fields struct {
content string
}
tests := []struct {
name string
fields fields
want *Ignore
wantErr bool
}{
{
name: "success: empty",
fields: fields{
content: "",
},
want: &Ignore{
paths: []string{`\.goit/.*`},
},
wantErr: false,
},
{
name: "success: some ignore list",
fields: fields{
content: "*.exe\ndir/",
},
want: &Ignore{
paths: []string{`\.goit/.*`, `.*\.exe`, `dir/.*`},
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tmpDir := t.TempDir()

goitignorePath := filepath.Join(tmpDir, ".goitignore")
f, err := os.Create(goitignorePath)
if err != nil {
t.Log(err)
}
_, err = f.WriteString(tt.fields.content)
if err != nil {
t.Log(err)
}
f.Close()

goitPath := filepath.Join(tmpDir, ".goit")
i, err := NewIgnore(goitPath)
if (err != nil) != tt.wantErr {
t.Errorf("got = %v, want = %v", err, tt.wantErr)
}
if !reflect.DeepEqual(i, tt.want) {
t.Errorf("got = %v, want = %v", i, tt.want)
}
})
}
}
2 changes: 2 additions & 0 deletions testdata/.goitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.exe
dir/dir2/