diff --git a/internal/core/config.go b/internal/core/config.go index 1425bbea..7e89146d 100644 --- a/internal/core/config.go +++ b/internal/core/config.go @@ -113,21 +113,29 @@ func (c Config) GroupConfigNamed(name string) (GroupConfig, error) { // GroupNameForPath returns the name of the GroupConfig matching the given // path, relative to the notebook. func (c Config) GroupNameForPath(path string) (string, error) { + var longestMatch string + var matchedName string + for name, config := range c.Groups { for _, groupPath := range config.Paths { matches, err := filepath.Match(groupPath, path) if err != nil { return "", errors.Wrapf(err, "failed to match group %s to %s", name, path) } else if matches { + // Early return if an exact match return name, nil } if strings.HasPrefix(path, groupPath+"/") { - return name, nil + // If the match is partial, find the longest prefix overlap + if len(groupPath) > len(longestMatch) { + longestMatch = groupPath + matchedName = name + } } } } - return "", nil + return matchedName, nil } // FormatConfig holds the configuration for document formats, such as Markdown. diff --git a/internal/core/config_test.go b/internal/core/config_test.go index 7148fef2..14c2e9b0 100644 --- a/internal/core/config_test.go +++ b/internal/core/config_test.go @@ -275,6 +275,34 @@ func TestParseComplete(t *testing.T) { }) } +func TestGroupNameForPathApplyDeepestMatch(t *testing.T) { + config := Config{ + Groups: map[string]GroupConfig{ + "parent": { + Paths: []string{"dir1"}, + }, + "child": { + Paths: []string{"dir1/dir2"}, + }, + "other": { + Paths: []string{"other"}, + }, + }, + } + + name, err := config.GroupNameForPath("dir1/dir2/note.md") + assert.Nil(t, err) + assert.Equal(t, name, "child") + + name, err = config.GroupNameForPath("dir1/note.md") + assert.Nil(t, err) + assert.Equal(t, name, "parent") + + name, err = config.GroupNameForPath("other/note.md") + assert.Nil(t, err) + assert.Equal(t, name, "other") +} + func TestParseMergesGroupConfig(t *testing.T) { conf, err := ParseConfig([]byte(` [note] diff --git a/tests/fixtures/issue-490/.zk/config.toml b/tests/fixtures/issue-490/.zk/config.toml new file mode 100644 index 00000000..166856cc --- /dev/null +++ b/tests/fixtures/issue-490/.zk/config.toml @@ -0,0 +1,18 @@ +[note] +filename = "untitled" + +[group.t1] +paths = ["dir1", "dir1/dir2/dir3"] + +[group.t1.note] +extension = "md" +template = "template1.md" + + +# This group sits between the two directories of t1. +[group.t2] +paths = ["dir1/dir2"] + +[group.t2.note] +extension = "md" +template = "template2.md" diff --git a/tests/fixtures/issue-490/.zk/templates/template1.md b/tests/fixtures/issue-490/.zk/templates/template1.md new file mode 100644 index 00000000..a56f4e52 --- /dev/null +++ b/tests/fixtures/issue-490/.zk/templates/template1.md @@ -0,0 +1 @@ +Template 1 diff --git a/tests/fixtures/issue-490/.zk/templates/template2.md b/tests/fixtures/issue-490/.zk/templates/template2.md new file mode 100644 index 00000000..3e9461a9 --- /dev/null +++ b/tests/fixtures/issue-490/.zk/templates/template2.md @@ -0,0 +1 @@ +Template 2 diff --git a/tests/fixtures/issue-490/dir1/dir2/dir3/.gitkeep b/tests/fixtures/issue-490/dir1/dir2/dir3/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/tests/issue-490.tesh b/tests/issue-490.tesh new file mode 100644 index 00000000..6d65be0b --- /dev/null +++ b/tests/issue-490.tesh @@ -0,0 +1,25 @@ +$ cd issue-490 + +# This test ensures that group rules do not override other group +# rules that are applied to child directories. + +# Test that group t1 rules are followed. +$ zk new dir1 --dry-run +>Template 1 +2>{{working-dir}}/dir1/untitled.md + +# Test that group t1 rules are followed. +$ zk new dir1/dir2/dir3 --dry-run +>Template 1 +2>{{working-dir}}/dir1/dir2/dir3/untitled.md + +# Test that group t2 rules are followed, signifying that nested group rules are +# functioning correctly. +$ zk new dir1/dir2 --dry-run +>Template 2 +2>{{working-dir}}/dir1/dir2/untitled.md + +# Test that explicit group override still works +$ zk new dir1/dir2 --group t1 --dry-run +>Template 1 +2>{{working-dir}}/dir1/dir2/untitled.md