Skip to content

Commit

Permalink
Merge pull request #34 from ysim/list-values-for-given-key
Browse files Browse the repository at this point in the history
List values for given key
  • Loading branch information
ysim committed Jul 29, 2020
2 parents 09bd8a5 + 9945782 commit 68df98e
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 30 deletions.
4 changes: 4 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
v0.3.0 (xxxx-xx-xx)

* Introduction of `list` subcommand that lists values for a given key. (#23)

v0.2.0 (2020-04-17)

* Introduction of `new` subcommand that creates new recipe file with given
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ binary_location="${HOME}/bin/cook"
bash_completion_dir ?= "${HOME}/.bash_completion.d"

.PHONY: build
build: main.go search.go validate.go parser.go create.go
go build -ldflags "-X main.version=$(version)" -o cook main.go search.go validate.go parser.go create.go
build: main.go search.go validate.go parser.go create.go list.go util.go
go build -ldflags "-X main.version=$(version)" -o cook main.go search.go validate.go parser.go create.go list.go util.go

.PHONY: local
local: build
Expand Down
27 changes: 25 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,36 @@ This will print the recipe to the screen with some light styling.

### Create a new recipe

cook -filename=beer-bread -f='tags=[baking,bread]' -f='ingredients=[flour,yeast]' new
cook new -filename=beer-bread -f='tags=[baking,bread]' -f='ingredients=[flour,yeast]'

This will create a recipe file at `${COOK_RECIPES_DIR}/beer-bread${COOK_RECIPES_EXTENSION}`
with the given attributes and open it for editing by default.

Only the `-filename` flag is mandatory; the rest can be omitted and
subsequently filled in while editing.
subsequently filled in while editing:

$ cook new -filename=dandan-noodles

...new file opened in $EDITOR...

---
name:
---
#

## INGREDIENTS

## INSTRUCTIONS

---
Source:

### List unique values for a key

cook list -key=tags

This will list, in alphabetical order, all the unique values for the `tags` key
as defined in the recipe files' YAML front matter blocks.

### Validate the formatting of your recipe files

Expand Down
60 changes: 60 additions & 0 deletions list.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package main

import (
"fmt"
log "github.com/sirupsen/logrus"
"os"
"path/filepath"
"sort"
)

func listValuesForKey(key string, values *[]string) filepath.WalkFunc {
return func(fullFilepath string, info os.FileInfo, err error) error {
shouldSkip := ShouldSkipFile(info, err)
if shouldSkip {
return nil
}

recipeFile, err := ParseFile(fullFilepath)
if err != nil {
log.WithFields(log.Fields{
"file": fullFilepath,
}).Warn(err.Error())
return nil
}

frontMatter, err := ParseFrontMatter(recipeFile.FrontMatter)
if err != nil {
log.WithFields(log.Fields{
"file": fullFilepath,
}).Warn("Unknown type detected in front matter")
}

valueOfKey := frontMatter[key]
for _, v := range valueOfKey {
if StringInSlice(v, *values) == false {
*values = append(*values, v)
}
}
return nil
}
}

func List(key string) {
if key == "" {
fmt.Println("Functionality to list all keys is not implemented yet. (#21)")
} else {
values := make([]string, 0)
listErr := filepath.Walk(prefix, listValuesForKey(key, &values))
if len(values) == 0 {
fmt.Printf("No values were found for key '%s'.\n", key)
return
}
sort.Strings(values)
PrintArrayOnNewlines(values)
if listErr != nil {
errMsg := "An error occurred while attempting to list values for key '%s'."
fmt.Printf(errMsg, key)
}
}
}
61 changes: 35 additions & 26 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,11 @@ func PrintUsageString() {
s := `Usage:
cook [recipe]
cook edit [recipe]
cook search key:value[[,|+]value...]
cook list -key=KEY
cook new -filename=FILENAME
cook search key:value
cook validate [recipe]
cook version
`
fmt.Printf(s)
}
Expand Down Expand Up @@ -193,43 +197,48 @@ func (i *flagArray) Set(value string) error {
var fieldFlags flagArray

func main() {
recipeFilename := flag.String("filename", "", "The recipe filename (without the extension).")
recipeName := flag.String("name", "", "The recipe name.")
flag.Var(&fieldFlags, "f", "An arbitrary field.")

var args []string
switch testArgs {
case nil:
flag.Parse()
args = flag.Args()
default:
args = testArgs
}
newSubcommandFlagset := flag.NewFlagSet("newFlagset", flag.ContinueOnError)
listSubcommandFlagset := flag.NewFlagSet("listFlagset", flag.ContinueOnError)

// `new` subcommand flag pointers
recipeFilename := newSubcommandFlagset.String("filename", "", "The recipe filename (without the extension).")
recipeName := newSubcommandFlagset.String("name", "", "The recipe name.")
newSubcommandFlagset.Var(&fieldFlags, "f", "An arbitrary field.")

// `list` subcommand flag pointers
keyPtr := listSubcommandFlagset.String("key", "", "The key name for which to list values.")

args := os.Args
switch len(args) {
case 0:
PrintUsageString()
case 1:
switch args[0] {
case "new":
CreateNewRecipe(*recipeFilename, *recipeName, fieldFlags)
case "search":
fmt.Println("Usage: cook search \"key:value\"")
PrintUsageString()
case 2:
switch args[1] {
case "edit", "new", "search":
PrintUsageString()
case "list":
List("")
case "validate":
ValidateFiles()
case "version":
PrintVersion()
default:
DisplayRecipe(GetFullFilepath(args[0]))
DisplayRecipe(GetFullFilepath(args[1]))
}
default:
switch args[0] {
case "search":
Search(args[1:])
switch args[1] {
case "edit":
EditRecipe(GetFullFilepath(args[1]))
EditRecipe(GetFullFilepath(args[2]))
case "new":
newSubcommandFlagset.Parse(args[2:])
CreateNewRecipe(*recipeFilename, *recipeName, fieldFlags)
case "list":
listSubcommandFlagset.Parse(args[2:])
List(*keyPtr)
case "search":
Search(args[2:])
case "validate":
ValidateSingleFile(GetFullFilepath(args[1]))
ValidateSingleFile(GetFullFilepath(args[2]))
default:
PrintUsageString()
}
Expand Down
20 changes: 20 additions & 0 deletions util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package main

import (
"fmt"
)

func StringInSlice(s string, slice []string) bool {
for _, i := range slice {
if s == i {
return true
}
}
return false
}

func PrintArrayOnNewlines(a []string) {
for _, v := range a {
fmt.Println(v)
}
}

0 comments on commit 68df98e

Please sign in to comment.