mirror of
https://github.com/beego/bee.git
synced 2025-06-11 03:10:40 +00:00
Refactor!
create sub packages delete unused code delete code from not use command cmdRouter,cmdTest, cmdRundocs make command plugins check with gosimple,staticcheck,go vet,unused,unconvert
This commit is contained in:
14
utils/doc_value.go
Normal file
14
utils/doc_value.go
Normal file
@ -0,0 +1,14 @@
|
||||
package utils
|
||||
|
||||
import "fmt"
|
||||
|
||||
type DocValue string
|
||||
|
||||
func (d *DocValue) String() string {
|
||||
return fmt.Sprint(*d)
|
||||
}
|
||||
|
||||
func (d *DocValue) Set(value string) error {
|
||||
*d = DocValue(value)
|
||||
return nil
|
||||
}
|
14
utils/list_opts.go
Normal file
14
utils/list_opts.go
Normal file
@ -0,0 +1,14 @@
|
||||
package utils
|
||||
|
||||
import "fmt"
|
||||
|
||||
type ListOpts []string
|
||||
|
||||
func (opts *ListOpts) String() string {
|
||||
return fmt.Sprint(*opts)
|
||||
}
|
||||
|
||||
func (opts *ListOpts) Set(value string) error {
|
||||
*opts = append(*opts, value)
|
||||
return nil
|
||||
}
|
15
utils/str_flag.go
Normal file
15
utils/str_flag.go
Normal file
@ -0,0 +1,15 @@
|
||||
package utils
|
||||
|
||||
import "fmt"
|
||||
|
||||
// The string flag list, implemented flag.Value interface
|
||||
type StrFlags []string
|
||||
|
||||
func (s *StrFlags) String() string {
|
||||
return fmt.Sprintf("%s", *s)
|
||||
}
|
||||
|
||||
func (s *StrFlags) Set(value string) error {
|
||||
*s = append(*s, value)
|
||||
return nil
|
||||
}
|
340
utils/utils.go
Normal file
340
utils/utils.go
Normal file
@ -0,0 +1,340 @@
|
||||
// Copyright 2013 bee authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License"): you may
|
||||
// not use this file except in compliance with the License. You may obtain
|
||||
// a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
// License for the specific language governing permissions and limitations
|
||||
// under the License.
|
||||
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"text/template"
|
||||
|
||||
beeLogger "github.com/beego/bee/logger"
|
||||
"github.com/beego/bee/logger/colors"
|
||||
)
|
||||
|
||||
// Go is a basic promise implementation: it wraps calls a function in a goroutine
|
||||
// and returns a channel which will later return the function's return value.
|
||||
func Go(f func() error) chan error {
|
||||
ch := make(chan error)
|
||||
go func() {
|
||||
ch <- f()
|
||||
}()
|
||||
return ch
|
||||
}
|
||||
|
||||
// IsExist returns whether a file or directory exists.
|
||||
func IsExist(path string) bool {
|
||||
_, err := os.Stat(path)
|
||||
return err == nil || os.IsExist(err)
|
||||
}
|
||||
|
||||
// GetGOPATHs returns all paths in GOPATH variable.
|
||||
func GetGOPATHs() []string {
|
||||
gopath := os.Getenv("GOPATH")
|
||||
var paths []string
|
||||
if runtime.GOOS == "windows" {
|
||||
gopath = strings.Replace(gopath, "\\", "/", -1)
|
||||
paths = strings.Split(gopath, ";")
|
||||
} else {
|
||||
paths = strings.Split(gopath, ":")
|
||||
}
|
||||
return paths
|
||||
}
|
||||
|
||||
// IsBeegoProject checks whether the current path is a Beego application or not
|
||||
func IsBeegoProject(thePath string) bool {
|
||||
mainFiles := []string{}
|
||||
hasBeegoRegex := regexp.MustCompile(`(?s)package main.*?import.*?\(.*?github.com/astaxie/beego".*?\).*func main()`)
|
||||
c := make(chan error)
|
||||
// Walk the application path tree to look for main files.
|
||||
// Main files must satisfy the 'hasBeegoRegex' regular expression.
|
||||
go func() {
|
||||
filepath.Walk(thePath, func(fpath string, f os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
// Skip sub-directories
|
||||
if !f.IsDir() {
|
||||
var data []byte
|
||||
data, err = ioutil.ReadFile(fpath)
|
||||
if err != nil {
|
||||
c <- err
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(hasBeegoRegex.Find(data)) > 0 {
|
||||
mainFiles = append(mainFiles, fpath)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
close(c)
|
||||
}()
|
||||
|
||||
if err := <-c; err != nil {
|
||||
beeLogger.Log.Fatalf("Unable to walk '%s' tree: %s", thePath, err)
|
||||
}
|
||||
|
||||
if len(mainFiles) > 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// SearchGOPATHs searchs the user GOPATH(s) for the specified application name.
|
||||
// It returns a boolean, the application's GOPATH and its full path.
|
||||
func SearchGOPATHs(app string) (bool, string, string) {
|
||||
gps := GetGOPATHs()
|
||||
if len(gps) == 0 {
|
||||
beeLogger.Log.Fatal("GOPATH environment variable is not set or empty")
|
||||
}
|
||||
|
||||
// Lookup the application inside the user workspace(s)
|
||||
for _, gopath := range gps {
|
||||
var currentPath string
|
||||
|
||||
if !strings.Contains(app, "src") {
|
||||
gopathsrc := path.Join(gopath, "src")
|
||||
currentPath = path.Join(gopathsrc, app)
|
||||
} else {
|
||||
currentPath = app
|
||||
}
|
||||
|
||||
if IsExist(currentPath) {
|
||||
return true, gopath, currentPath
|
||||
}
|
||||
}
|
||||
return false, "", ""
|
||||
}
|
||||
|
||||
// askForConfirmation uses Scanln to parse user input. A user must type in "yes" or "no" and
|
||||
// then press enter. It has fuzzy matching, so "y", "Y", "yes", "YES", and "Yes" all count as
|
||||
// confirmations. If the input is not recognized, it will ask again. The function does not return
|
||||
// until it gets a valid response from the user. Typically, you should use fmt to print out a question
|
||||
// before calling askForConfirmation. E.g. fmt.Println("WARNING: Are you sure? (yes/no)")
|
||||
func AskForConfirmation() bool {
|
||||
var response string
|
||||
_, err := fmt.Scanln(&response)
|
||||
if err != nil {
|
||||
beeLogger.Log.Fatalf("%s", err)
|
||||
}
|
||||
okayResponses := []string{"y", "Y", "yes", "Yes", "YES"}
|
||||
nokayResponses := []string{"n", "N", "no", "No", "NO"}
|
||||
if containsString(okayResponses, response) {
|
||||
return true
|
||||
} else if containsString(nokayResponses, response) {
|
||||
return false
|
||||
} else {
|
||||
fmt.Println("Please type yes or no and then press enter:")
|
||||
return AskForConfirmation()
|
||||
}
|
||||
}
|
||||
|
||||
func containsString(slice []string, element string) bool {
|
||||
for _, elem := range slice {
|
||||
if elem == element {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// snake string, XxYy to xx_yy
|
||||
func SnakeString(s string) string {
|
||||
data := make([]byte, 0, len(s)*2)
|
||||
j := false
|
||||
num := len(s)
|
||||
for i := 0; i < num; i++ {
|
||||
d := s[i]
|
||||
if i > 0 && d >= 'A' && d <= 'Z' && j {
|
||||
data = append(data, '_')
|
||||
}
|
||||
if d != '_' {
|
||||
j = true
|
||||
}
|
||||
data = append(data, d)
|
||||
}
|
||||
return strings.ToLower(string(data[:]))
|
||||
}
|
||||
|
||||
func CamelString(s string) string {
|
||||
data := make([]byte, 0, len(s))
|
||||
j := false
|
||||
k := false
|
||||
num := len(s) - 1
|
||||
for i := 0; i <= num; i++ {
|
||||
d := s[i]
|
||||
if !k && d >= 'A' && d <= 'Z' {
|
||||
k = true
|
||||
}
|
||||
if d >= 'a' && d <= 'z' && (j || !k) {
|
||||
d = d - 32
|
||||
j = false
|
||||
k = true
|
||||
}
|
||||
if k && d == '_' && num > i && s[i+1] >= 'a' && s[i+1] <= 'z' {
|
||||
j = true
|
||||
continue
|
||||
}
|
||||
data = append(data, d)
|
||||
}
|
||||
return string(data[:])
|
||||
}
|
||||
|
||||
// camelCase converts a _ delimited string to camel case
|
||||
// e.g. very_important_person => VeryImportantPerson
|
||||
func CamelCase(in string) string {
|
||||
tokens := strings.Split(in, "_")
|
||||
for i := range tokens {
|
||||
tokens[i] = strings.Title(strings.Trim(tokens[i], " "))
|
||||
}
|
||||
return strings.Join(tokens, "")
|
||||
}
|
||||
|
||||
// formatSourceCode formats source files
|
||||
func FormatSourceCode(filename string) {
|
||||
cmd := exec.Command("gofmt", "-w", filename)
|
||||
if err := cmd.Run(); err != nil {
|
||||
beeLogger.Log.Warnf("Error while running gofmt: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// CloseFile attempts to close the passed file
|
||||
// or panics with the actual error
|
||||
func CloseFile(f *os.File) {
|
||||
err := f.Close()
|
||||
MustCheck(err)
|
||||
}
|
||||
|
||||
// MustCheck panics when the error is not nil
|
||||
func MustCheck(err error) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// WriteToFile creates a file and writes content to it
|
||||
func WriteToFile(filename, content string) {
|
||||
f, err := os.Create(filename)
|
||||
MustCheck(err)
|
||||
defer CloseFile(f)
|
||||
_, err = f.WriteString(content)
|
||||
MustCheck(err)
|
||||
}
|
||||
|
||||
// IsDebugEnabled checks if DEBUG_ENABLED is set or not
|
||||
func IsDebugEnabled() bool {
|
||||
debugMode := os.Getenv("DEBUG_ENABLED")
|
||||
return map[string]bool{"1": true, "0": false}[debugMode]
|
||||
}
|
||||
|
||||
// __FILE__ returns the file name in which the function was invoked
|
||||
func FILE() string {
|
||||
_, file, _, _ := runtime.Caller(1)
|
||||
return file
|
||||
}
|
||||
|
||||
// __LINE__ returns the line number at which the function was invoked
|
||||
func LINE() int {
|
||||
_, _, line, _ := runtime.Caller(1)
|
||||
return line
|
||||
}
|
||||
|
||||
// BeeFuncMap returns a FuncMap of functions used in different templates.
|
||||
func BeeFuncMap() template.FuncMap {
|
||||
return template.FuncMap{
|
||||
"trim": strings.TrimSpace,
|
||||
"bold": colors.Bold,
|
||||
"headline": colors.MagentaBold,
|
||||
"foldername": colors.RedBold,
|
||||
"endline": EndLine,
|
||||
"tmpltostr": TmplToString,
|
||||
}
|
||||
}
|
||||
|
||||
// TmplToString parses a text template and return the result as a string.
|
||||
func TmplToString(tmpl string, data interface{}) string {
|
||||
t := template.New("tmpl").Funcs(BeeFuncMap())
|
||||
template.Must(t.Parse(tmpl))
|
||||
|
||||
var doc bytes.Buffer
|
||||
err := t.Execute(&doc, data)
|
||||
MustCheck(err)
|
||||
|
||||
return doc.String()
|
||||
}
|
||||
|
||||
// EndLine returns the a newline escape character
|
||||
func EndLine() string {
|
||||
return "\n"
|
||||
}
|
||||
|
||||
func Tmpl(text string, data interface{}) {
|
||||
output := colors.NewColorWriter(os.Stderr)
|
||||
|
||||
t := template.New("Usage").Funcs(BeeFuncMap())
|
||||
template.Must(t.Parse(text))
|
||||
|
||||
err := t.Execute(output, data)
|
||||
if err != nil {
|
||||
beeLogger.Log.Error(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func CheckEnv(appname string) (apppath, packpath string, err error) {
|
||||
gps := GetGOPATHs()
|
||||
if len(gps) == 0 {
|
||||
beeLogger.Log.Fatal("GOPATH environment variable is not set or empty")
|
||||
}
|
||||
currpath, _ := os.Getwd()
|
||||
currpath = path.Join(currpath, appname)
|
||||
for _, gpath := range gps {
|
||||
gsrcpath := path.Join(gpath, "src")
|
||||
if strings.HasPrefix(currpath, gsrcpath) {
|
||||
packpath = strings.Replace(currpath[len(gsrcpath)+1:], string(filepath.Separator), "/", -1)
|
||||
return currpath, packpath, nil
|
||||
}
|
||||
}
|
||||
|
||||
// In case of multiple paths in the GOPATH, by default
|
||||
// we use the first path
|
||||
gopath := gps[0]
|
||||
|
||||
beeLogger.Log.Warn("You current workdir is not inside $GOPATH/src.")
|
||||
beeLogger.Log.Debugf("GOPATH: %s", FILE(), LINE(), gopath)
|
||||
|
||||
gosrcpath := path.Join(gopath, "src")
|
||||
apppath = path.Join(gosrcpath, appname)
|
||||
|
||||
if _, e := os.Stat(apppath); !os.IsNotExist(e) {
|
||||
err = fmt.Errorf("Cannot create application without removing '%s' first.", apppath)
|
||||
beeLogger.Log.Errorf("Path '%s' already exists", apppath)
|
||||
return
|
||||
}
|
||||
packpath = strings.Join(strings.Split(apppath[len(gosrcpath)+1:], string(filepath.Separator)), "/")
|
||||
return
|
||||
}
|
||||
|
||||
func PrintErrorAndExit(message, errorTemplate string) {
|
||||
Tmpl(fmt.Sprintf(errorTemplate, message), nil)
|
||||
os.Exit(2)
|
||||
}
|
Reference in New Issue
Block a user