Skip to content

Commit

Permalink
feat: YAML support and more filenames (#158)
Browse files Browse the repository at this point in the history
* Add YAML support
* Fix nil pointer when `--name` is passed

---------

Closes #154 
Closes #157
Signed-off-by: AlexNg <[email protected]>
  • Loading branch information
caffeine-addictt authored Oct 7, 2024
2 parents d2999a8 + 283f820 commit 6838145
Show file tree
Hide file tree
Showing 39 changed files with 1,003 additions and 791 deletions.
28 changes: 4 additions & 24 deletions cmd/commands/check.go
Original file line number Diff line number Diff line change
@@ -1,50 +1,30 @@
package commands

import (
"path/filepath"
"strings"

"github.com/caffeine-addictt/waku/internal/errors"
"github.com/caffeine-addictt/waku/internal/log"
"github.com/caffeine-addictt/waku/internal/template"
"github.com/caffeine-addictt/waku/internal/utils"
"github.com/spf13/cobra"
)

var CheckCmd = &cobra.Command{
Use: "check <path>",
Aliases: []string{"ch", "c", "verify"},
Short: "check if template.json is valid",
Long: "Check if your current template.json is valid",
Short: "check if config is valid",
Long: "Check if your current config is valid",
Args: cobra.MaximumNArgs(1),
SilenceErrors: true,
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {
// Check for naming
if len(args) == 1 && !strings.HasSuffix(args[0], "template.json") {
return errors.NewWakuErrorf("name your file template.json")
}

// Resolve file path
var filePath string
if len(args) == 1 {
filePath = args[0]
} else {
filePath = "template.json"
}
filePath = filepath.Clean(filePath)

log.Debugf("checking if %s is a file\n", filePath)
ok, err := utils.IsFile(filePath)
if err != nil {
return errors.NewWakuErrorf("failed to check if %s is a file: %v", filePath, err)
}
if !ok {
return errors.NewWakuErrorf("%s does not exist or is not a file", filePath)
filePath = "."
}

log.Debugf("checking if %s is a valid template\n", filePath)
if _, err := template.ParseConfig(filePath); err != nil {
if _, _, err := template.ParseConfig(filePath); err != nil {
return errors.ToWakuError(err)
}

Expand Down
24 changes: 16 additions & 8 deletions cmd/commands/new.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,23 @@ var NewCmd = &cobra.Command{
var projectRootDir string
var license license.License

log.Debugln("Creating name and license prompts...")
namePrompt := template.PromptForProjectName(&name, &projectRootDir)
licenseSelect, err := template.PromptForLicense(&license)
if err != nil {
return errors.ToWakuError(err)
}

if err := huh.NewForm(
huh.NewGroup(template.PromptForProjectName(&name, &projectRootDir)),
huh.NewGroup(licenseSelect),
).WithAccessible(options.GlobalOpts.Accessible).Run(); err != nil {
initialPrompts := make([]*huh.Group, 0, 2)
if namePrompt != nil {
initialPrompts = append(initialPrompts, huh.NewGroup(namePrompt))
}
if licenseSelect != nil {
initialPrompts = append(initialPrompts, huh.NewGroup(licenseSelect))
}

log.Debugln("running prompts...")
if err := huh.NewForm(initialPrompts...).WithAccessible(options.GlobalOpts.Accessible).Run(); err != nil {
return errors.ToWakuError(err)
}

Expand Down Expand Up @@ -91,8 +99,8 @@ var NewCmd = &cobra.Command{
}

// Parse template.json
log.Infoln("Parsing template.json...")
tmpl, err := template.ParseConfig(filepath.Join(rootDir, "template.json"))
log.Infoln("Parsing config...")
configFilePath, tmpl, err := template.ParseConfig(rootDir)
if err != nil {
return errors.ToWakuError(err)
}
Expand Down Expand Up @@ -182,7 +190,7 @@ var NewCmd = &cobra.Command{
ignoreRules := types.NewSet(
".git/",
"LICENSE*",
"template.json",
configFilePath,
)
if tmpl.Ignore != nil {
ignoreRules.Union(types.Set[string](*tmpl.Ignore))
Expand Down Expand Up @@ -241,7 +249,7 @@ func init() {
func AddNewCmdFlags(cmd *cobra.Command) {
cmd.Flags().VarP(&options.NewOpts.Repo, "repo", "r", "source repository to template from")
cmd.Flags().VarP(&options.NewOpts.Branch, "branch", "b", "branch to clone from")
cmd.Flags().VarP(&options.NewOpts.Directory, "directory", "D", "directory where 'template.json' is located")
cmd.Flags().VarP(&options.NewOpts.Directory, "directory", "D", "directory where config is located")
cmd.Flags().VarP(&options.NewOpts.Name, "name", "n", "name of the project")
cmd.Flags().VarP(&options.NewOpts.License, "license", "l", "license to use for the project")
cmd.Flags().VarP(&options.NewOpts.Style, "style", "S", "which style to use")
Expand Down
4 changes: 3 additions & 1 deletion cmd/options/new.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@ func (o *NewOptions) Validate() error {
return err
}
if o.Branch.Value() == "" {
if err := o.Branch.Set("v" + version.Version); err != nil {
newBranch := "v" + version.Version
log.Debugf("Setting branch to %s\n", newBranch)
if err := o.Branch.Set(newBranch); err != nil {
return err
}
}
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ require (
github.com/muesli/roff v0.1.0
github.com/spf13/cobra v1.8.1
github.com/stretchr/testify v1.9.0
gopkg.in/yaml.v3 v3.0.1
)

require (
Expand Down Expand Up @@ -60,5 +61,4 @@ require (
golang.org/x/sys v0.25.0 // indirect
golang.org/x/text v0.18.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
13 changes: 10 additions & 3 deletions internal/license/store.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
package license

import (
"fmt"
"io"
"net/http"

"github.com/caffeine-addictt/waku/pkg/version"
"github.com/caffeine-addictt/waku/cmd/options"
"github.com/caffeine-addictt/waku/internal/log"
"github.com/goccy/go-json"
)

const (
LICENSE_LIST = "license.json"
BASE_URL = "https://raw.githubusercontent.com/caffeine-addictt/waku/v" + version.Version + "/licenses/"
BASE_URL = "https://raw.githubusercontent.com/caffeine-addictt/waku/%s/licenses/"
)

// The global "cache" per say so we only
Expand All @@ -24,7 +26,9 @@ func GetLicenses() (*[]License, error) {
return Licenses, nil
}

req, err := http.NewRequest(http.MethodGet, BASE_URL+LICENSE_LIST, http.NoBody)
url := fmt.Sprintf(BASE_URL, options.NewOpts.Branch.Value()) + LICENSE_LIST
log.Infof("Fetching licenses from %s...\n", url)
req, err := http.NewRequest(http.MethodGet, url, http.NoBody)
if err != nil {
return nil, err
}
Expand All @@ -37,6 +41,7 @@ func GetLicenses() (*[]License, error) {
}
defer res.Body.Close()

log.Debugln("Reading http stream")
body, err := io.ReadAll(res.Body)
if err != nil {
return nil, err
Expand All @@ -45,6 +50,8 @@ func GetLicenses() (*[]License, error) {
var l struct {
Licenses []License `json:"licenses"`
}

log.Debugln("Unmarshalling license json")
if err := json.Unmarshal(body, &l); err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/license/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type License struct {
// The filename in 'licenses/'
Filename string `json:"filename"`

// That values the licens wants
// That values the license wants
Wants LicenseWants `json:"wants"`
}

Expand Down
6 changes: 3 additions & 3 deletions internal/template/ignore.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,14 @@ func handleMatching(paths *types.Set[string], pattern string) []string {

// convert pattern parts to regex-able
nonRecursePartsCount := 0
isRecusive := false
isRecursive := false
newPattern := "^"

a:
for nonRecursePartsCount < len(patternParts) {
switch patternParts[nonRecursePartsCount] {
case "**", "":
isRecusive = true
isRecursive = true
break a
default:
s := patternParts[nonRecursePartsCount]
Expand Down Expand Up @@ -97,7 +97,7 @@ a:
continue
}

if !isRecusive || (isRecusive && len(pParts) > nonRecursePartsCount) {
if !isRecursive || (isRecursive && len(pParts) > nonRecursePartsCount) {
matching = append(matching, p)
}
}
Expand Down
51 changes: 27 additions & 24 deletions internal/template/parse_config.go
Original file line number Diff line number Diff line change
@@ -1,45 +1,48 @@
package template

import (
"bufio"
"encoding/json"
"os"
"io"
"path/filepath"
"strings"

"github.com/caffeine-addictt/waku/internal/log"
"github.com/caffeine-addictt/waku/pkg/config"
"gopkg.in/yaml.v3"
)

func ParseConfig(filePath string) (*config.TemplateJson, error) {
file, err := os.Open(filepath.Clean(filePath))
func ParseConfig(filePath string) (string, *config.TemplateJson, error) {
path, file, err := GetWakuConfig(filePath)
if err != nil {
return nil, err
return "", nil, err
}
defer file.Close()

var template config.TemplateJson
var jsonData string

// Read the entire file content
scanner := bufio.NewScanner(file)
for scanner.Scan() {
jsonData += scanner.Text()
}

if err := scanner.Err(); err != nil {
return nil, err
log.Debugf("reading config file at %v\n", filePath)
data, err := io.ReadAll(file)
if err != nil {
return "", nil, err
}

// Unmarshal JSON data
log.Debugln("Unmarshalling JSON data from " + filePath)
if err := json.Unmarshal([]byte(jsonData), &template); err != nil {
return nil, err
var template config.TemplateJson
if strings.HasSuffix(path, "json") {
log.Debugln("unmarshalling JSON data from " + path)
if err := json.Unmarshal(data, &template); err != nil {
return "", nil, err
}
} else {
log.Debugln("unmarshalling YAML data from " + path)
if err := yaml.Unmarshal(data, &template); err != nil {
return "", nil, err
}
}

log.Debugf("Unmarshalled JSON data: %+v\n", template)
log.Infoln("Validating JSON data from " + filePath)
if err := template.Validate(filepath.Dir(filePath)); err != nil {
return nil, err
log.Debugf("unmarshalled data: %+v\n", template)
log.Infoln("validating data from " + path)
if err := template.Validate(filepath.Dir(path)); err != nil {
return "", nil, err
}

return &template, nil
return path, &template, nil
}
2 changes: 2 additions & 0 deletions internal/template/prompting.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

"github.com/caffeine-addictt/waku/cmd/options"
"github.com/caffeine-addictt/waku/internal/license"
"github.com/caffeine-addictt/waku/internal/log"
"github.com/caffeine-addictt/waku/internal/searching"
"github.com/caffeine-addictt/waku/internal/sorting"
"github.com/caffeine-addictt/waku/internal/types"
Expand Down Expand Up @@ -100,6 +101,7 @@ func validateLicense(ll *[]license.License, optsL []string, val string, setV *li
func PromptForProjectName(name, projectRootDir *string) *huh.Input {
if options.NewOpts.Name.Value() != "" {
if err := validateProjectName(options.NewOpts.Name.Value(), name, projectRootDir); err == nil {
log.Debugf("name prefilled and is valid: %s\n", options.NewOpts.Name.Value())
return nil
}
}
Expand Down
Loading

0 comments on commit 6838145

Please sign in to comment.