diff options
author | Steve Manuel <nilslice@gmail.com> | 2016-11-24 10:37:54 -0800 |
---|---|---|
committer | Steve Manuel <nilslice@gmail.com> | 2016-11-24 10:37:54 -0800 |
commit | 04344fd03a609af37ec95a6c8279a45c17d5de70 (patch) | |
tree | 0129828f4a6eb5c1cfb2a02124fc4a14a22f4006 /cmd/ponzu/generate.go | |
parent | 6f5893828077eb0034dca01344f3742eb5cd5fa6 (diff) |
adding initial support to generate content type from more descriptive cli args
Diffstat (limited to 'cmd/ponzu/generate.go')
-rw-r--r-- | cmd/ponzu/generate.go | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/cmd/ponzu/generate.go b/cmd/ponzu/generate.go new file mode 100644 index 0000000..9325d1d --- /dev/null +++ b/cmd/ponzu/generate.go @@ -0,0 +1,192 @@ +package main + +import ( + "bytes" + "fmt" + "go/format" + "html/template" + "os" + "path/filepath" + "strings" +) + +type generateType struct { + Name string + Initial string + Fields []generateField +} + +type generateField struct { + Name string + TypeName string + JSONName string +} + +// blog title:string Author:string PostCategory:string content:string some_thing:int +func parseType(args []string) (generateType, error) { + t := generateType{ + Name: fieldName(args[0]), + } + t.Initial = strings.ToLower(string(t.Name[0])) + + fields := args[1:] + for _, field := range fields { + f, err := parseField(field) + if err != nil { + return generateType{}, err + } + + t.Fields = append(t.Fields, f) + } + + return t, nil +} + +func parseField(raw string) (generateField, error) { + // title:string + if !strings.Contains(raw, ":") { + return generateField{}, fmt.Errorf("Invalid generate argument. [%s]", raw) + } + + pair := strings.Split(raw, ":") + field := generateField{ + Name: fieldName(pair[0]), + TypeName: strings.ToLower(pair[1]), + JSONName: fieldJSONName(pair[0]), + } + + return field, nil +} + +// get the initial field name passed and check it for all possible cases +// MyTitle:string myTitle:string my_title:string -> MyTitle +// error-message:string -> ErrorMessage +func fieldName(name string) string { + // remove _ or - if first character + if name[0] == '-' || name[0] == '_' { + name = name[1:] + } + + // remove _ or - if last character + if name[len(name)-1] == '-' || name[len(name)-1] == '_' { + name = name[:len(name)-1] + } + + // upcase the first character + name = strings.ToUpper(string(name[0])) + name[1:] + + // remove _ or - character, and upcase the character immediately following + for i := 0; i < len(name); i++ { + r := rune(name[i]) + if isUnderscore(r) || isHyphen(r) { + up := strings.ToUpper(string(name[i+1])) + name = name[:i] + up + name[i+2:] + } + } + + return name +} + +// get the initial field name passed and convert to json-like name +// MyTitle:string myTitle:string my_title:string -> my_title +// error-message:string -> error-message +func fieldJSONName(name string) string { + // remove _ or - if first character + if name[0] == '-' || name[0] == '_' { + name = name[1:] + } + + // downcase the first character + name = strings.ToLower(string(name[0])) + name[1:] + + // check for uppercase character, downcase and insert _ before it if i-1 + // isn't already _ or - + for i := 0; i < len(name); i++ { + r := rune(name[i]) + if isUpper(r) { + low := strings.ToLower(string(r)) + if name[i-1] == '_' || name[i-1] == '-' { + name = name[:i] + low + name[i+1:] + } else { + name = name[:i] + "_" + low + name[i+1:] + } + } + } + + return name +} + +func isUpper(char rune) bool { + if char >= 'A' && char <= 'Z' { + return true + } + + return false +} + +func isUnderscore(char rune) bool { + return char == '_' +} + +func isHyphen(char rune) bool { + return char == '-' +} + +func generateContentType(args []string, path string) error { + name := args[0] + fileName := strings.ToLower(name) + ".go" + + // open file in ./content/ dir + // if exists, alert user of conflict + pwd, err := os.Getwd() + if err != nil { + return err + } + + if path != "" { + pwd = path + } + + contentDir := filepath.Join(pwd, "content") + filePath := filepath.Join(contentDir, fileName) + + if _, err := os.Stat(filePath); !os.IsNotExist(err) { + return fmt.Errorf("Please remove '%s' before executing this command.", fileName) + } + + // no file exists.. ok to write new one + file, err := os.Create(filePath) + defer file.Close() + if err != nil { + return err + } + + // parse type info from args + gt, err := parseType(args) + if err != nil { + return fmt.Errorf("Failed to parse type args: %s", err.Error()) + } + + tmpl, err := template.ParseFiles("contentType.tmpl") + if err != nil { + return fmt.Errorf("Failed to parse template: %s", err.Error()) + } + + buf := &bytes.Buffer{} + err = tmpl.Execute(buf, gt) + if err != nil { + return fmt.Errorf("Failed to execute template: %s", err.Error()) + } + + fmtBuf, err := format.Source(buf.Bytes()) + if err != nil { + return fmt.Errorf("Failed to format template: %s", err.Error()) + } + + _, err = file.Write(fmtBuf) + if err != nil { + return fmt.Errorf("Failed to write generated file buffer: %s", err.Error()) + } + + return nil +} |