diff --git a/utils/utils.go b/utils/utils.go index f1bda8a3..86c249f8 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -16,10 +16,22 @@ import ( "github.com/spf13/hugo/commands" ) -// RunHugo is used to run hugo -func RunHugo(c *config.Config) { - commands.HugoCmd.ParseFlags(c.Flags) - commands.HugoCmd.Run(commands.HugoCmd, make([]string, 0)) +// CanBeEdited checks if a filename has a supported extension +func CanBeEdited(filename string) bool { + extensions := [...]string{".markdown", ".md", + ".json", ".toml", ".yaml", + ".css", ".sass", ".scss", + ".js", + ".html", + } + + for _, extension := range extensions { + if strings.HasSuffix(filename, extension) { + return true + } + } + + return false } // CopyFile is used to copy a file @@ -46,22 +58,33 @@ func CopyFile(old, new string) error { return nil } -// CanBeEdited checks if a filename has a supported extension -func CanBeEdited(filename string) bool { - extensions := [...]string{".markdown", ".md", - ".json", ".toml", ".yaml", - ".css", ".sass", ".scss", - ".js", - ".html", +// Defined checks if variable is defined in a struct +func Defined(data interface{}, field string) bool { + t := reflect.Indirect(reflect.ValueOf(data)).Type() + + if t.Kind() != reflect.Struct { + log.Print("Non-struct type not allowed.") + return false } - for _, extension := range extensions { - if strings.HasSuffix(filename, extension) { - return true + _, b := t.FieldByName(field) + return b +} + +// Dict allows to send more than one variable into a template +func Dict(values ...interface{}) (map[string]interface{}, error) { + if len(values)%2 != 0 { + return nil, errors.New("invalid dict call") + } + dict := make(map[string]interface{}, len(values)/2) + for i := 0; i < len(values); i += 2 { + key, ok := values[i].(string) + if !ok { + return nil, errors.New("dict keys must be strings") } + dict[key] = values[i+1] } - - return false + return dict, nil } // GetTemplate is used to get a ready to use template based on the url and on @@ -105,35 +128,6 @@ func GetTemplate(r *http.Request, functions template.FuncMap, templates ...strin return tpl, nil } -// Dict allows to send more than one variable into a template -func Dict(values ...interface{}) (map[string]interface{}, error) { - if len(values)%2 != 0 { - return nil, errors.New("invalid dict call") - } - dict := make(map[string]interface{}, len(values)/2) - for i := 0; i < len(values); i += 2 { - key, ok := values[i].(string) - if !ok { - return nil, errors.New("dict keys must be strings") - } - dict[key] = values[i+1] - } - return dict, nil -} - -// Defined checks if variable is defined in a struct -func Defined(data interface{}, field string) bool { - t := reflect.Indirect(reflect.ValueOf(data)).Type() - - if t.Kind() != reflect.Struct { - log.Print("Non-struct type not allowed.") - return false - } - - _, b := t.FieldByName(field) - return b -} - // IsMap checks if some variable is a map func IsMap(sth interface{}) bool { return reflect.ValueOf(sth).Kind() == reflect.Map @@ -144,6 +138,32 @@ func IsSlice(sth interface{}) bool { return reflect.ValueOf(sth).Kind() == reflect.Slice } +// ParseComponents parses the components of an URL creating an array +func ParseComponents(r *http.Request) []string { + //The URL that the user queried. + path := r.URL.Path + path = strings.TrimSpace(path) + //Cut off the leading and trailing forward slashes, if they exist. + //This cuts off the leading forward slash. + if strings.HasPrefix(path, "/") { + path = path[1:] + } + //This cuts off the trailing forward slash. + if strings.HasSuffix(path, "/") { + cutOffLastCharLen := len(path) - 1 + path = path[:cutOffLastCharLen] + } + //We need to isolate the individual components of the path. + components := strings.Split(path, "/") + return components +} + +// RunHugo is used to run hugo +func RunHugo(c *config.Config) { + commands.HugoCmd.ParseFlags(c.Flags) + commands.HugoCmd.Run(commands.HugoCmd, make([]string, 0)) +} + // SplitCapitalize splits a string by its uppercase letters and capitalize the // first letter of the string func SplitCapitalize(name string) string { @@ -168,23 +188,3 @@ func SplitCapitalize(name string) string { return name } - -// ParseComponents parses the components of an URL creating an array -func ParseComponents(r *http.Request) []string { - //The URL that the user queried. - path := r.URL.Path - path = strings.TrimSpace(path) - //Cut off the leading and trailing forward slashes, if they exist. - //This cuts off the leading forward slash. - if strings.HasPrefix(path, "/") { - path = path[1:] - } - //This cuts off the trailing forward slash. - if strings.HasSuffix(path, "/") { - cutOffLastCharLen := len(path) - 1 - path = path[:cutOffLastCharLen] - } - //We need to isolate the individual components of the path. - components := strings.Split(path, "/") - return components -} diff --git a/utils/utils_test.go b/utils/utils_test.go new file mode 100644 index 00000000..56634573 --- /dev/null +++ b/utils/utils_test.go @@ -0,0 +1,39 @@ +package utils + +import "testing" + +type canBeEdited struct { + file string + result bool +} + +var canBeEditedPairs = []canBeEdited{ + {"file.markdown", true}, + {"file.md", true}, + {"file.json", true}, + {"file.toml", true}, + {"file.yaml", true}, + {"file.css", true}, + {"file.sass", true}, + {"file.scss", true}, + {"file.js", true}, + {"file.html", true}, + {"file.git", false}, + {"file.log", false}, + {"file.sh", false}, + {"file.png", false}, + {"file.jpg", false}, +} + +func TestCanBeEdited(t *testing.T) { + for _, pair := range canBeEditedPairs { + v := CanBeEdited(pair.file) + if v != pair.result { + t.Error( + "For", pair.file, + "expected", pair.result, + "got", v, + ) + } + } +}