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

feat: search repos in a nested project structure #4

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
14 changes: 10 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,27 @@ Download build binary from the [releases](https://github.com/suin/git-remind/rel

## Configuration

Add `remind.paths` to your `.gitconfig`, using your own absolute path to the repository directories.
Add `remind.paths` to your `.gitconfig`, using your own absolute path to the repository directories.

```text:.gitconfig
[remind]
paths = /Users/you/projects/foo,/Users/you/projects/bar
```

If you have some git repositories (e.g. `~/projects/foo` and `~/projects/bar`) in the same directory (e.g. in `~/projects`) , you may specify the path using wildcard (e.g.`/Users/you/projects/*`):

If you have some git repositories (e.g. `~/projects/foo` and `~/projects/bar`) in the same directory (e.g. in `~/projects`) , you may specify the path using wildcard (e.g. `/Users/you/projects/*`):

```text:.gitconfig
[remind]
paths = /Users/you/projects/*
```

If you have a nested git repository structure (e.g. `~/projects/foobar/foo`, `~/projects/foobar/bar` and `~/projects/foo`), you may specify the path using a double asterisk (e.g. `/Users/you/projects/**`):

```text:.gitconfig
[remind]
paths = /Users/you/projects/**
```

You can also utilise the `git config` command to configure git-remind to avoid the manually editing of the `.gitconfig`.

```bash
Expand Down Expand Up @@ -76,7 +82,7 @@ C /Users/suin/projects/myapp1
CP /Users/suin/projects/myapp2
```

#### Show all status including up-to-date repositories
#### Show all status including up-to-date repositories

```
$ git-remind status -a
Expand Down
41 changes: 37 additions & 4 deletions infra/filesystem_repos.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package infra

import (
"github.com/suin/git-remind/domain"
"io/fs"
"os"
"path/filepath"
"strings"

"github.com/suin/git-remind/domain"
)

var FilesystemRepos domain.GetReposByPathPattern = func(patterns domain.GetPathPatterns) (repos []string, err error) {
Expand All @@ -12,9 +15,17 @@ var FilesystemRepos domain.GetReposByPathPattern = func(patterns domain.GetPathP
return
}
for _, pathPattern := range pathPatterns {
paths, err2 := filepath.Glob(string(pathPattern))
if err2 != nil {
return repos, err2
if strings.HasSuffix(string(pathPattern), "/**") {
path := strings.TrimSuffix(string(pathPattern), "/**")
dirs, err := searchForGitDirs(path)
if err != nil {
return repos, err
}
repos = append(repos, dirs...)
}
paths, err := filepath.Glob(string(pathPattern))
if err != nil {
return repos, err
}
for _, path := range paths {
isDir, _ := isDirectory(path + "/.git")
Expand All @@ -33,3 +44,25 @@ func isDirectory(path string) (bool, error) {
}
return fileInfo.IsDir(), err
}

func searchForGitDirs(root string) ([]string, error) {
var skipPath string
var matchedPaths []string
err := filepath.WalkDir(
root,
func(path string, d fs.DirEntry, err error) error {
if err != nil {
return err
}
if d.IsDir() && d.Name() == ".git" && skipPath != path {
skipPath = path
matchedPaths = append(matchedPaths, strings.TrimSuffix(path, "/.git"))
}
return nil
},
)
if err != nil {
return nil, err
}
return matchedPaths, nil
}