diff --git a/README.md b/README.md index e9558338..1bfa92ce 100644 --- a/README.md +++ b/README.md @@ -138,6 +138,7 @@ defaults: refetchIntervalMinutes: 30 # will refetch all sections every 30 minutes repoPaths: # configure where to locate repos when checking out PRs default_path: ~/code/repos # fallback value if none of the other paths match + :owner/:repo: ~/src/github.com/:owner/:repo # template if you always clone github repos in a consistent location dlvhdr/*: ~/code/repos/dlvhdr/* # will match dlvhdr/repo-name to ~/code/repos/dlvhdr/repo-name dlvhdr/gh-dash: ~/code/gh-dash # will not match wildcard and map to specified path keybindings: # optional, define custom keybindings - see more info below @@ -216,6 +217,7 @@ An exact match for the full repo name to a full path takes priority over a match ```yaml repoPaths: default_path: ~/code/repos # fallback value if none of the other paths match + :owner/:repo: ~/src/github.com/:owner/:repo # template if you always clone github repos in a consistent location dlvhdr/*: ~/code/repos/dlvhdr/* # will match dlvhdr/repo-name to ~/code/repos/dlvhdr/repo-name dlvhdr/gh-dash: ~/code/gh-dash # will not match wildcard and map to specified path ``` diff --git a/ui/common/repopath.go b/ui/common/repopath.go index 4fee0dfc..e7aa4659 100644 --- a/ui/common/repopath.go +++ b/ui/common/repopath.go @@ -48,6 +48,10 @@ func GetRepoLocalPath(repoName string, cfgPaths map[string]string) (string, bool return fmt.Sprintf("%s/%s", strings.TrimSuffix(wildcardPath, "/*"), repo), true } + if template, ok := cfgPaths[":owner/:repo"]; ok { + return strings.ReplaceAll(strings.ReplaceAll(template, ":owner", owner), ":repo", repo), true + } + if defaultPath, found := cfgPaths["default_path"]; found { p := strings.TrimSuffix(defaultPath, "/*") return filepath.Join(p, repo), true diff --git a/ui/common/repopath_test.go b/ui/common/repopath_test.go index b6af8e68..eca0139c 100644 --- a/ui/common/repopath_test.go +++ b/ui/common/repopath_test.go @@ -19,6 +19,12 @@ var configPathsWithDefaultPath = map[string]string{ "default_path": "/path/to/user/dev", } +var configPathsWithOwnerRepoTemplate = map[string]string{ + "user/repo": "/path/to/the_repo", + "org/*": "/path/to/the_org/*", + ":owner/:repo": "/path/to/github.com/:owner/:repo", +} + func TestGetRepoLocalPath(t *testing.T) { testCases := map[string]struct { repo string @@ -56,6 +62,36 @@ func TestGetRepoLocalPath(t *testing.T) { found: true, configPaths: configPathsWithDefaultPath, }, + "with :owner/:repo template: exact match": { + repo: "user/repo", + want: "/path/to/the_repo", + found: true, + configPaths: configPathsWithOwnerRepoTemplate, + }, + "with :owner/:repo template: no match for this sibling repo": { + repo: "user/another_repo", + want: "/path/to/github.com/user/another_repo", + found: true, + configPaths: configPathsWithOwnerRepoTemplate, + }, + "with :owner/:repo template: wildcard repo match": { + repo: "org/some_repo", + want: "/path/to/the_org/some_repo", + found: true, + configPaths: configPathsWithOwnerRepoTemplate, + }, + "with :owner/:repo template: general fallback": { + repo: "any-owner/any-repo", + want: "/path/to/github.com/any-owner/any-repo", + found: true, + configPaths: configPathsWithOwnerRepoTemplate, + }, + "with :owner/:repo template: repeated :repo substitution": { + repo: "any-owner/any-repo", + want: "src/github.com/any-owner/any-repo/any-repo", + found: true, + configPaths: map[string]string{":owner/:repo": "src/github.com/:owner/:repo/:repo"}, + }, } for name, tc := range testCases {