Skip to content

Commit

Permalink
add group search command and add more info to group schema
Browse files Browse the repository at this point in the history
  • Loading branch information
candrewlee14 committed Mar 26, 2024
1 parent d8a2a0a commit c5014ef
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 38 deletions.
78 changes: 41 additions & 37 deletions cmd/group/add/group_add.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,48 +55,52 @@ The "group add" subcommand installs a group of packages.
}
}
group := args[0]
groupConf, repoPath, err := pkgparse.ParseGroupConfigLocal(cfg.PkgRepos, group)
return InstallGroup(cfg, group)
},
}

func InstallGroup(cfg *config.Config, group string) error {
groupConf, repoPath, err := pkgparse.ParseGroupConfigLocal(cfg.PkgRepos, group)
if err != nil {
return err
}

var pkgsToInstall []string
if allFlag {
pkgsToInstall = groupConf.Packages
} else {
pkgInfos, err := pkgparse.ParseGroupPackages(repoPath, groupConf.Packages)
if err != nil {
return err
}

var pkgsToInstall []string
if allFlag {
pkgsToInstall = groupConf.Packages
} else {
pkgInfos, err := pkgparse.ParseGroupPackages(repoPath, groupConf.Packages)
if err != nil {
return err
}
infoLines := make([]string, len(pkgInfos))
for i, pkgInfo := range pkgInfos {
infoLines[i] = color.CyanString(pkgInfo.Title) + color.HiBlackString(" - ") + pkgInfo.Tagline
}
prompt := &survey.MultiSelect{
Message: "Select packages from group " + color.YellowString(group) + " to install:",
Options: infoLines,
PageSize: 10,
}
var indices []int
survey.AskOne(prompt, &indices)
for _, val := range indices {
pkgsToInstall = append(pkgsToInstall, groupConf.Packages[val])
}
infoLines := make([]string, len(pkgInfos))
for i, pkgInfo := range pkgInfos {
infoLines[i] = color.CyanString(pkgInfo.Title) + color.HiBlackString(" - ") + pkgInfo.Tagline
}
if len(pkgsToInstall) == 0 {
color.HiBlack("No packages selected for installation.")
} else {
pkgs := add.InstallAllPkgs(cfg.PkgRepos, pkgsToInstall, false, true)
for _, pkg := range pkgs {
fmt.Print(pkg.PkgConf.InstallNotes())
}
if len(pkgs) != len(pkgsToInstall) {
return errors.New("Not all packages installed successfully")
}
color.Green("All %d selected packages from group %s are installed", len(pkgsToInstall), color.YellowString(group))
prompt := &survey.MultiSelect{
Message: "Select packages from group " + color.YellowString(group) + " to install:",
Options: infoLines,
PageSize: 10,
}
return nil
},
var indices []int
survey.AskOne(prompt, &indices)
for _, val := range indices {
pkgsToInstall = append(pkgsToInstall, groupConf.Packages[val])
}
}
if len(pkgsToInstall) == 0 {
color.HiBlack("No packages selected for installation.")
} else {
pkgs := add.InstallAllPkgs(cfg.PkgRepos, pkgsToInstall, false, true)
for _, pkg := range pkgs {
fmt.Print(pkg.PkgConf.InstallNotes())
}
if len(pkgs) != len(pkgsToInstall) {
return errors.New("Not all packages installed successfully")
}
color.Green("All %d selected packages from group %s are installed", len(pkgsToInstall), color.YellowString(group))
}
return nil
}

func init() {
Expand Down
2 changes: 2 additions & 0 deletions cmd/group/group.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package group
import (
groupadd "github.com/candrewlee14/webman/cmd/group/add"
groupremove "github.com/candrewlee14/webman/cmd/group/remove"
groupsearch "github.com/candrewlee14/webman/cmd/group/search"

"github.com/spf13/cobra"
)
Expand All @@ -24,4 +25,5 @@ webman group remove
func init() {
GroupCmd.AddCommand(groupadd.AddCmd)
GroupCmd.AddCommand(groupremove.RemoveCmd)
GroupCmd.AddCommand(groupsearch.SearchCmd)
}
125 changes: 125 additions & 0 deletions cmd/group/search/group_search.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package search

import (
"fmt"
"io"
"os"
"sort"
"strings"

"github.com/candrewlee14/webman/cmd/group/add"
"github.com/candrewlee14/webman/config"
"github.com/candrewlee14/webman/pkgparse"
"github.com/candrewlee14/webman/utils"

"github.com/AlecAivazis/survey/v2"
"github.com/fatih/color"
"github.com/ktr0731/go-fuzzyfinder"
"github.com/spf13/cobra"
)

var doRefresh bool

var SearchCmd = &cobra.Command{
Use: "search",
Short: "search for a group",
Long: `
The "search" subcommand starts an interactive window to find and display info about a group`,
Example: `webman group search`,
RunE: func(cmd *cobra.Command, args []string) error {
if len(args) != 0 {
return cmd.Help()
}
cfg, err := config.Load()
if err != nil {
return err
}
// if local recipe flag is not set
if utils.RecipeDirFlag == "" {
// only refresh if not using local
for _, pkgRepo := range cfg.PkgRepos {
shouldRefresh, err := pkgRepo.ShouldRefreshRecipes(cfg.RefreshInterval)
if err != nil {
return err
}
if shouldRefresh || doRefresh {
color.HiBlue("Refreshing package recipes for %q...", pkgRepo.Name)
if err = pkgRepo.RefreshRecipes(); err != nil {
color.Red("%v", err)
}
}
}
}

groupInfos := make([]*pkgparse.PkgGroupConfig, 0)
for _, pkgRepo := range cfg.PkgRepos {
files, err := os.ReadDir(pkgRepo.GroupPath())
if err != nil {
return err
}
for _, file := range files {
group := strings.Split(file.Name(), utils.GroupRecipeExt)[0]
groupInfo, err := pkgparse.ParseGroupConfigInRepo(pkgRepo, group)
if err != nil {
return err
}
groupInfos = append(groupInfos, groupInfo)
}
}
sort.Slice(groupInfos, func(i, j int) bool {
return groupInfos[i].Title < groupInfos[j].Title
})

idx, err := fuzzyfinder.Find(
groupInfos,
func(i int) string {
return groupInfos[i].Title + " - " + groupInfos[i].Tagline
},
fuzzyfinder.WithPreviewWindow(func(i, w, h int) string {
if i == -1 {
return ""
}
preview := fmt.Sprintf("%s: %s\n\n%s:\n %s\n\n%s:\n%s\n\n%s:\n%s\n",
"📚 Title",
groupInfos[i].Title,
"💾 Tagline",
groupInfos[i].Tagline,
"🛈 Description",
groupInfos[i].Description,
"🗐 Package List",
strings.Join(groupInfos[i].Packages, ", "),
)
return wrapText(preview, w)
}))
if err != nil {
color.HiBlack("No group selected.")
return nil
}
groupName := groupInfos[idx].Title
prompt := &survey.Confirm{
Message: "Would you like to install the latest version of " + color.CyanString(groupName) + "?",
}
shouldInstall := false
if err := survey.AskOne(prompt, &shouldInstall); err != nil || !shouldInstall {
color.HiBlack("No group selected.")
return nil
}
return add.InstallGroup(cfg, groupName)
},
}

func init() {
SearchCmd.Flags().BoolVar(&doRefresh, "refresh", false, "force refresh of package recipes")
}

func wrapText(text string, width int) string {
prevI := -1
var buf strings.Builder
for i, ch := range text {
if ch == '\n' || i-prevI > (width/2-6) {
io.WriteString(&buf, strings.TrimSpace(text[prevI+1:i+1])+"\n")
prevI = i
}
}
return buf.String()
}
17 changes: 16 additions & 1 deletion pkgparse/group_parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ import (
)

type PkgGroupConfig struct {
Packages []string `yaml:"packages"`
Title string `yaml:"title"`
Tagline string `yaml:"tagline"`
Description string `yaml:"description"`
Packages []string `yaml:"packages"`
}

func ParseGroupConfig(r io.Reader, name string) (*PkgGroupConfig, error) {
Expand All @@ -34,6 +37,18 @@ func ParseGroupConfig(r io.Reader, name string) (*PkgGroupConfig, error) {
return &groupConf, nil
}

func ParseGroupConfigInRepo(pkgRepo *config.PkgRepo, group string) (*PkgGroupConfig, error) {
groupPath := filepath.Join(pkgRepo.Path(), "groups", group+utils.GroupRecipeExt)
fi, err := os.Open(groupPath)
if err != nil {
return nil, err
}
defer fi.Close()

groupCfg, err := ParseGroupConfig(fi, group)
return groupCfg, err
}

func ParseGroupConfigLocal(pkgRepos []*config.PkgRepo, group string) (*PkgGroupConfig, string, error) {
var groupConfPath string
var repo string
Expand Down
15 changes: 15 additions & 0 deletions schema/group_schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,21 @@
],
"additionalProperties": false,
"properties": {
"title": {
"description": "Group title",
"type": "string",
"additionalProperties": false
},
"tagline": {
"description": "Group tagline",
"type": "string",
"additionalProperties": false
},
"description": {
"description": "Group description",
"type": "string",
"additionalProperties": false
},
"packages": {
"description": "List of packages",
"type": "array",
Expand Down

0 comments on commit c5014ef

Please sign in to comment.