diff --git a/cmd/search.go b/cmd/search.go index aad572d..10bc64d 100644 --- a/cmd/search.go +++ b/cmd/search.go @@ -1,22 +1,33 @@ package cmd import ( + "fmt" + clog "github.com/niclasvaneyk/keepac/internal/changelog" "github.com/spf13/cobra" ) // searchCmd represents the grep command var searchCmd = &cobra.Command{ - Use: "search", - Short: "Searches for strings in the nearest changelog and prints matches within their context", - Long: ``, + Use: "search [query]", + Aliases: []string{"grep"}, + Short: "Searches for strings in the nearest changelog and prints matches within their context", + Long: ``, + Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { changelog, _, err := clog.ResolveChangelog() if err != nil { return err } - return nil + query := args[0] + result := clog.Search(changelog, query) + + if result == "" { + fmt.Println("Nothing matched your query!") + } + + return clog.Show(result + "\n") }, } diff --git a/internal/changelog/search.go b/internal/changelog/search.go index 488e0e0..c68c9ee 100644 --- a/internal/changelog/search.go +++ b/internal/changelog/search.go @@ -3,28 +3,55 @@ package changelog import "strings" func Search(changelog *Changelog, query string) string { - matchingBounds := make([]string, 0) + output := make([]string, 0) nextRelease := changelog.Releases.Next if nextRelease != nil { + includedRelease := false for _, section := range nextRelease.Sections { + includedSection := false for _, item := range section.Items { if strings.Contains(item, query) { - matchingBounds = append(matchingBounds, "- "+item) + if !includedRelease { + includedRelease = true + output = append(output, "## "+changelog.ContentWithin(&nextRelease.HeadlineBounds)) + output = append(output, "") + } + + if !includedSection { + includedSection = true + output = append(output, "### "+ChangeTypeLabel(section.Type)) + output = append(output, "") + } + + output = append(output, "- "+item) } } } } for _, release := range changelog.Releases.Past { + includedRelease := false for _, section := range release.Sections { + includedSection := false for _, item := range section.Items { if strings.Contains(item, query) { - matchingBounds = append(matchingBounds, item) + if !includedRelease { + includedRelease = true + output = append(output, "## "+changelog.ContentWithin(&release.HeadlineBounds)) + output = append(output, "") + } + + if !includedSection { + includedSection = true + output = append(output, "### "+ChangeTypeLabel(section.Type)) + output = append(output, "") + } + output = append(output, "- "+item) } } } } - return strings.Join(matchingBounds, "\n") + return strings.Join(output, "\n") }