1
0
mirror of https://github.com/taigrr/wtf synced 2025-01-18 04:03:14 -08:00

Move a bunch of code out of utils.go and into dedicated files

This commit is contained in:
Chris Cummer 2019-08-05 11:16:26 -07:00
parent 4e46fff145
commit ecd95ba2d2
12 changed files with 287 additions and 237 deletions

47
utils/conversions.go Normal file
View File

@ -0,0 +1,47 @@
package utils
import (
"strconv"
)
/* -------------------- Map Conversion -------------------- */
// MapToStrs takes a map of interfaces and returns a map of strings
func MapToStrs(aMap map[string]interface{}) map[string]string {
results := make(map[string]string)
for key, val := range aMap {
results[key] = val.(string)
}
return results
}
/* -------------------- Slice Conversion -------------------- */
// ToInts takes a slice of interfaces and returns a slice of ints
func ToInts(slice []interface{}) []int {
results := []int{}
for _, val := range slice {
results = append(results, val.(int))
}
return results
}
// ToStrs takes a slice of interfaces and returns a slice of strings
func ToStrs(slice []interface{}) []string {
results := []string{}
for _, val := range slice {
switch val.(type) {
case int:
results = append(results, strconv.Itoa(val.(int)))
case string:
results = append(results, val.(string))
}
}
return results
}

44
utils/conversions_test.go Normal file
View File

@ -0,0 +1,44 @@
package utils
import (
"testing"
. "github.com/stretchr/testify/assert"
)
func Test_MapToStrs(t *testing.T) {
expected := map[string]string{
"a": "a",
"b": "b",
"c": "c",
}
source := make(map[string]interface{})
for _, val := range expected {
source[val] = val
}
Equal(t, expected, MapToStrs(source))
}
func Test_ToInts(t *testing.T) {
expected := []int{1, 2, 3}
source := make([]interface{}, len(expected))
for idx, val := range expected {
source[idx] = val
}
Equal(t, expected, ToInts(source))
}
func Test_ToStrs(t *testing.T) {
expected := []string{"cat", "dog", "rat"}
source := make([]interface{}, len(expected))
for idx, val := range expected {
source[idx] = val
}
Equal(t, expected, ToStrs(source))
}

35
utils/email_addresses.go Normal file
View File

@ -0,0 +1,35 @@
package utils
import (
"strings"
)
// NameFromEmail takes an email address and returns the part that comes before the @ symbol
//
// Example:
//
// NameFromEmail("test_user@example.com")
// > "Test_user"
//
func NameFromEmail(email string) string {
parts := strings.Split(email, "@")
return strings.Title(strings.Replace(parts[0], ".", " ", -1))
}
// NamesFromEmails takes a slice of email addresses and returns a slice of the parts that
// come before the @ symbol
//
// Example:
//
// NamesFromEmail("test_user@example.com", "other_user@example.com")
// > []string{"Test_user", "Other_user"}
//
func NamesFromEmails(emails []string) []string {
names := []string{}
for _, email := range emails {
names = append(names, NameFromEmail(email))
}
return names
}

View File

@ -0,0 +1,22 @@
package utils
import (
"testing"
. "github.com/stretchr/testify/assert"
)
func Test_NameFromEmail(t *testing.T) {
Equal(t, "", NameFromEmail(""))
Equal(t, "Chris Cummer", NameFromEmail("chris.cummer@me.com"))
}
func Test_NamesFromEmails(t *testing.T) {
var result []string
result = NamesFromEmails([]string{})
Equal(t, []string{}, result)
result = NamesFromEmails([]string{"chris.cummer@me.com", "chriscummer@me.com"})
Equal(t, []string{"Chris Cummer", "Chriscummer"}, result)
}

View File

@ -10,47 +10,7 @@ import (
"github.com/wtfutil/wtf/cfg" "github.com/wtfutil/wtf/cfg"
) )
func lowercaseTitle(title string) string { /* -------------------- Exported Functions -------------------- */
if title == "" {
return ""
}
r, n := utf8.DecodeRuneInString(title)
return string(unicode.ToLower(r)) + title[n:]
}
var (
openColorRegex = regexp.MustCompile(`\[.*?\]`)
)
func StripColorTags(input string) string {
return openColorRegex.ReplaceAllString(input, "")
}
func helpFromValue(field reflect.StructField) string {
result := ""
optional, err := strconv.ParseBool(field.Tag.Get("optional"))
if err != nil {
optional = false
}
help := field.Tag.Get("help")
if optional {
help = "Optional " + help
}
values := field.Tag.Get("values")
if help != "" {
result += "\n\n " + lowercaseTitle(field.Name)
result += "\n " + help
if values != "" {
result += "\n Values: " + values
}
}
return result
}
func HelpFromInterface(item interface{}) string { func HelpFromInterface(item interface{}) string {
result := "" result := ""
@ -78,3 +38,45 @@ func HelpFromInterface(item interface{}) string {
return result return result
} }
// StripColorTags removes tcell color tags from a given string
func StripColorTags(input string) string {
openColorRegex := regexp.MustCompile(`\[.*?\]`)
return openColorRegex.ReplaceAllString(input, "")
}
/* -------------------- Unexported Functions -------------------- */
func helpFromValue(field reflect.StructField) string {
result := ""
optional, err := strconv.ParseBool(field.Tag.Get("optional"))
if err != nil {
optional = false
}
help := field.Tag.Get("help")
if optional {
help = "Optional " + help
}
values := field.Tag.Get("values")
if help != "" {
result += "\n\n " + lowercaseTitle(field.Name)
result += "\n " + help
if values != "" {
result += "\n Values: " + values
}
}
return result
}
func lowercaseTitle(title string) string {
if title == "" {
return ""
}
r, n := utf8.DecodeRuneInString(title)
return string(unicode.ToLower(r)) + title[n:]
}

View File

@ -10,21 +10,7 @@ import (
"path/filepath" "path/filepath"
) )
// Dir returns the home directory for the executing user. // ExpandHomeDir expands the path to include the home directory if the path
// An error is returned if a home directory cannot be detected.
func Home() (string, error) {
currentUser, err := user.Current()
if err != nil {
return "", err
}
if currentUser.HomeDir == "" {
return "", errors.New("cannot find user-specific home dir")
}
return currentUser.HomeDir, nil
}
// Expand expands the path to include the home directory if the path
// is prefixed with `~`. If it isn't prefixed with `~`, the path is // is prefixed with `~`. If it isn't prefixed with `~`, the path is
// returned as-is. // returned as-is.
func ExpandHomeDir(path string) (string, error) { func ExpandHomeDir(path string) (string, error) {
@ -47,3 +33,18 @@ func ExpandHomeDir(path string) (string, error) {
return filepath.Join(dir, path[1:]), nil return filepath.Join(dir, path[1:]), nil
} }
// Home returns the home directory for the executing user.
// An error is returned if a home directory cannot be detected.
func Home() (string, error) {
currentUser, err := user.Current()
if err != nil {
return "", err
}
if currentUser.HomeDir == "" {
return "", errors.New("cannot find user-specific home dir")
}
return currentUser.HomeDir, nil
}

View File

@ -1,5 +1,6 @@
package utils package utils
// OpenFileUtil defines the system utility to use to open files
var OpenFileUtil = "open" var OpenFileUtil = "open"
// Init initializes global settings in the wtf package // Init initializes global settings in the wtf package

12
utils/init_test.go Normal file
View File

@ -0,0 +1,12 @@
package utils
import (
"testing"
. "github.com/stretchr/testify/assert"
)
func Test_Init(t *testing.T) {
Init("cats")
Equal(t, OpenFileUtil, "cats")
}

48
utils/text.go Normal file
View File

@ -0,0 +1,48 @@
package utils
import (
"fmt"
"strings"
"github.com/rivo/tview"
)
// CenterText takes a string and a width and pads the left and right of the string with
// empty spaces to ensure that the string is in the middle of the returned value
//
// Example:
//
// x := CenterText("cat", 11)
// > " cat "
//
func CenterText(str string, width int) string {
if width < 0 {
width = 0
}
return fmt.Sprintf("%[1]*s", -width, fmt.Sprintf("%[1]*s", (width+len(str))/2, str))
}
// HighlightableHelper pads the given text with blank spaces to the width of the view
// containing it. This is helpful for extending row highlighting across the entire width
// of the view
func HighlightableHelper(view *tview.TextView, input string, idx, offset int) string {
fmtStr := fmt.Sprintf(`["%d"][""]`, idx)
_, _, w, _ := view.GetInnerRect()
fmtStr += input
fmtStr += PadRow(offset, w+1)
fmtStr += `[""]` + "\n"
return fmtStr
}
// PadRow returns a padding for a row to make it the full width of the containing widget.
// Useful for ensurig row highlighting spans the full width (I suspect tcell has a better
// way to do this, but I haven't yet found it)
func PadRow(offset int, max int) string {
padSize := max - offset
if padSize < 0 {
padSize = 0
}
return strings.Repeat(" ", padSize)
}

19
utils/text_test.go Normal file
View File

@ -0,0 +1,19 @@
package utils
import (
"testing"
. "github.com/stretchr/testify/assert"
)
func Test_CenterText(t *testing.T) {
Equal(t, "cat", CenterText("cat", -9))
Equal(t, "cat", CenterText("cat", 0))
Equal(t, " cat ", CenterText("cat", 9))
}
func Test_PadRow(t *testing.T) {
Equal(t, "", PadRow(0, 0))
Equal(t, "", PadRow(5, 2))
Equal(t, " ", PadRow(1, 2))
}

View File

@ -6,10 +6,7 @@ import (
"os/exec" "os/exec"
"regexp" "regexp"
"runtime" "runtime"
"strconv"
"strings" "strings"
"github.com/rivo/tview"
) )
const ( const (
@ -24,22 +21,6 @@ const (
TimestampFormat = "2006-01-02T15:04:05-0700" TimestampFormat = "2006-01-02T15:04:05-0700"
) )
// CenterText takes a string and a width and pads the left and right of the string with
// empty spaces to ensure that the string is in the middle of the returned value
//
// Example:
//
// x := CenterText("cat", 11)
// > " cat "
//
func CenterText(str string, width int) string {
if width < 0 {
width = 0
}
return fmt.Sprintf("%[1]*s", -width, fmt.Sprintf("%[1]*s", (width+len(str))/2, str))
}
// ExecuteCommand executes an external command on the local machine as the current user // ExecuteCommand executes an external command on the local machine as the current user
func ExecuteCommand(cmd *exec.Cmd) string { func ExecuteCommand(cmd *exec.Cmd) string {
if cmd == nil { if cmd == nil {
@ -92,36 +73,6 @@ func FindMatch(pattern string, data string) [][]string {
return r.FindAllStringSubmatch(data, -1) return r.FindAllStringSubmatch(data, -1)
} }
// NameFromEmail takes an email address and returns the part that comes before the @ symbol
//
// Example:
//
// NameFromEmail("test_user@example.com")
// > "Test_user"
//
func NameFromEmail(email string) string {
parts := strings.Split(email, "@")
return strings.Title(strings.Replace(parts[0], ".", " ", -1))
}
// NamesFromEmails takes a slice of email addresses and returns a slice of the parts that
// come before the @ symbol
//
// Example:
//
// NamesFromEmail("test_user@example.com", "other_user@example.com")
// > []string{"Test_user", "Other_user"}
//
func NamesFromEmails(emails []string) []string {
names := []string{}
for _, email := range emails {
names = append(names, NameFromEmail(email))
}
return names
}
// OpenFile opens the file defined in `path` via the operating system // OpenFile opens the file defined in `path` via the operating system
func OpenFile(path string) { func OpenFile(path string) {
if (strings.HasPrefix(path, "http://")) || (strings.HasPrefix(path, "https://")) { if (strings.HasPrefix(path, "http://")) || (strings.HasPrefix(path, "https://")) {
@ -141,18 +92,6 @@ func OpenFile(path string) {
} }
} }
// PadRow returns a padding for a row to make it the full width of the containing widget.
// Useful for ensurig row highlighting spans the full width (I suspect tcell has a better
// way to do this, but I haven't yet found it)
func PadRow(offset int, max int) string {
padSize := max - offset
if padSize < 0 {
padSize = 0
}
return strings.Repeat(" ", padSize)
}
// ReadFileBytes reads the contents of a file and returns those contents as a slice of bytes // ReadFileBytes reads the contents of a file and returns those contents as a slice of bytes
func ReadFileBytes(filePath string) ([]byte, error) { func ReadFileBytes(filePath string) ([]byte, error) {
fileData, err := ioutil.ReadFile(filePath) fileData, err := ioutil.ReadFile(filePath)
@ -162,54 +101,3 @@ func ReadFileBytes(filePath string) ([]byte, error) {
return fileData, nil return fileData, nil
} }
/* -------------------- Map Conversion -------------------- */
// MapToStrs takes a map of interfaces and returns a map of strings
func MapToStrs(aMap map[string]interface{}) map[string]string {
results := make(map[string]string)
for key, val := range aMap {
results[key] = val.(string)
}
return results
}
/* -------------------- Slice Conversion -------------------- */
// ToInts takes a slice of interfaces and returns a slice of ints
func ToInts(slice []interface{}) []int {
results := []int{}
for _, val := range slice {
results = append(results, val.(int))
}
return results
}
// ToStrs takes a slice of interfaces and returns a slice of strings
func ToStrs(slice []interface{}) []string {
results := []string{}
for _, val := range slice {
switch val.(type) {
case int:
results = append(results, strconv.Itoa(val.(int)))
case string:
results = append(results, val.(string))
}
}
return results
}
func HighlightableHelper(view *tview.TextView, input string, idx, offset int) string {
fmtStr := fmt.Sprintf(`["%d"][""]`, idx)
_, _, w, _ := view.GetInnerRect()
fmtStr += input
fmtStr += PadRow(offset, w+1)
fmtStr += `[""]` + "\n"
return fmtStr
}

View File

@ -7,17 +7,6 @@ import (
. "github.com/stretchr/testify/assert" . "github.com/stretchr/testify/assert"
) )
func Test_Init(t *testing.T) {
Init("cats")
Equal(t, OpenFileUtil, "cats")
}
func Test_CenterText(t *testing.T) {
Equal(t, "cat", CenterText("cat", -9))
Equal(t, "cat", CenterText("cat", 0))
Equal(t, " cat ", CenterText("cat", 9))
}
func Test_ExecuteCommand(t *testing.T) { func Test_ExecuteCommand(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
@ -59,61 +48,3 @@ func Test_ExcludeWhenTrue(t *testing.T) {
Equal(t, true, Exclude([]string{"cat", "dog", "rat"}, "bat")) Equal(t, true, Exclude([]string{"cat", "dog", "rat"}, "bat"))
Equal(t, false, Exclude([]string{"cat", "dog", "rat"}, "dog")) Equal(t, false, Exclude([]string{"cat", "dog", "rat"}, "dog"))
} }
func Test_NameFromEmail(t *testing.T) {
Equal(t, "", NameFromEmail(""))
Equal(t, "Chris Cummer", NameFromEmail("chris.cummer@me.com"))
}
func Test_NamesFromEmails(t *testing.T) {
var result []string
result = NamesFromEmails([]string{})
Equal(t, []string{}, result)
result = NamesFromEmails([]string{"chris.cummer@me.com", "chriscummer@me.com"})
Equal(t, []string{"Chris Cummer", "Chriscummer"}, result)
}
func Test_PadRow(t *testing.T) {
Equal(t, "", PadRow(0, 0))
Equal(t, "", PadRow(5, 2))
Equal(t, " ", PadRow(1, 2))
}
func Test_MapToStrs(t *testing.T) {
expected := map[string]string{
"a": "a",
"b": "b",
"c": "c",
}
source := make(map[string]interface{})
for _, val := range expected {
source[val] = val
}
Equal(t, expected, MapToStrs(source))
}
func Test_ToInts(t *testing.T) {
expected := []int{1, 2, 3}
source := make([]interface{}, len(expected))
for idx, val := range expected {
source[idx] = val
}
Equal(t, expected, ToInts(source))
}
func Test_ToStrs(t *testing.T) {
expected := []string{"cat", "dog", "rat"}
source := make([]interface{}, len(expected))
for idx, val := range expected {
source[idx] = val
}
Equal(t, expected, ToStrs(source))
}