Skip to content

Commit

Permalink
chore: refactor cmd/* (wip)
Browse files Browse the repository at this point in the history
  • Loading branch information
soulteary committed Jan 5, 2024
1 parent a3c511b commit e27ed91
Show file tree
Hide file tree
Showing 11 changed files with 610 additions and 544 deletions.
120 changes: 120 additions & 0 deletions cmd/cli.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
package FlareCMD

import (
"os"
"regexp"
"strings"

"github.com/soulteary/flare/internal/version"
flags "github.com/spf13/pflag"

FlareDefine "github.com/soulteary/flare/config/define"
FlareModel "github.com/soulteary/flare/config/model"
)

func parseCLI(baseFlags FlareModel.Flags) FlareModel.Flags {

var cliFlags = new(FlareModel.Flags)
options := flags.NewFlagSet("appFlags", flags.ContinueOnError)
options.SortFlags = false

// port
options.IntVarP(&cliFlags.Port, _KEY_PORT, _KEY_PORT_SHORT, FlareDefine.DEFAULT_PORT, "指定监听端口")
// guide
options.BoolVarP(&cliFlags.EnableGuide, _KEY_ENABLE_GUIDE, _KEY_ENABLE_GUIDE_SHORT, FlareDefine.DEFAULT_ENABLE_GUIDE, "启用应用向导")
// visibility
options.StringVarP(&cliFlags.Visibility, _KEY_VISIBILITY, _KEY_VISIBILITY_SHORT, FlareDefine.DEFAULT_VISIBILITY, "调整网站整体可见性")
// mini_request
options.BoolVarP(&cliFlags.EnableMinimumRequest, _KEY_MINI_REQUEST, _KEY_MINI_REQUEST_SHORT, FlareDefine.DEFAULT_ENABLE_MINI_REQUEST, "使用请求最小化模式")
options.BoolVar(&cliFlags.EnableMinimumRequest, _KEY_MINI_REQUEST_OLD, FlareDefine.DEFAULT_ENABLE_MINI_REQUEST, "使用请求最小化模式")
_ = options.MarkDeprecated(_KEY_MINI_REQUEST_OLD, "please use --"+_KEY_MINI_REQUEST+" instead")
// offline
options.BoolVarP(&cliFlags.EnableOfflineMode, _KEY_ENABLE_OFFLINE, _KEY_ENABLE_OFFLINE_SHORT, FlareDefine.DEFAULT_ENABLE_OFFLINE, "启用离线模式")
// disable_login
options.BoolVarP(&cliFlags.DisableLoginMode, _KEY_DISABLE_LOGIN, _KEY_DISABLE_LOGIN_SHORT, FlareDefine.DEFAULT_DISABLE_LOGIN, "禁用账号登陆")
options.BoolVar(&cliFlags.DisableLoginMode, _KEY_DISABLE_LOGIN_OLD, FlareDefine.DEFAULT_DISABLE_LOGIN, "禁用账号登陆")
_ = options.MarkDeprecated(_KEY_DISABLE_LOGIN_OLD, "please use --"+_KEY_DISABLE_LOGIN+" instead")
// 启用废弃日志警告
options.BoolVarP(&cliFlags.EnableDeprecatedNotice, _KEY_ENABLE_DEPRECATED_NOTICE, _KEY_ENABLE_DEPRECATED_NOTICE_SHORT, FlareDefine.DEFAULT_ENABLE_DEPRECATED_NOTICE, "启用废弃日志警告")
options.BoolVarP(&cliFlags.EnableEditor, _KEY_ENABLE_EDITOR, _KEY_ENABLE_EDITOR_SHORT, FlareDefine.DEFAULT_ENABLE_EDITOR, "启用编辑器")
// 禁用 CSP
options.BoolVarP(&cliFlags.DisableCSP, _KEY_DISABLE_CSP, _KEY_DISABLE_CSP_SHORT, FlareDefine.DEFAULT_DISABLE_CSP, "禁用CSP")
// 其他
options.BoolVarP(&cliFlags.ShowVersion, "version", "v", false, "显示应用版本号")
options.BoolVarP(&cliFlags.ShowHelp, "help", "h", false, "显示帮助")

_ = options.Parse(os.Args)

exit := ExcuteCLI(cliFlags, options)
if exit {
os.Exit(0)
}
GetVersion(true)

// 用于判断参数是否存在
keys := make(map[string]bool)
trimValue := regexp.MustCompile(`=.*`)
for _, key := range os.Args[1:] {
if key[:2] == "--" {
keys[trimValue.ReplaceAllString(key[2:], "")] = true
} else if key[:1] == "-" {
keys[trimValue.ReplaceAllString(key[1:], "")] = true
}
}

if keys[_KEY_PORT] || keys[_KEY_PORT_SHORT] {
baseFlags.Port = cliFlags.Port
}

if keys[_KEY_MINI_REQUEST] || keys[_KEY_MINI_REQUEST_SHORT] || keys[_KEY_MINI_REQUEST_OLD] {
baseFlags.EnableMinimumRequest = cliFlags.EnableMinimumRequest
}

if keys[_KEY_DISABLE_LOGIN] || keys[_KEY_DISABLE_LOGIN_SHORT] || keys[_KEY_DISABLE_LOGIN_OLD] {
baseFlags.DisableLoginMode = cliFlags.DisableLoginMode
}

if keys[_KEY_DISABLE_CSP] || keys[_KEY_DISABLE_CSP_SHORT] {
baseFlags.DisableCSP = cliFlags.DisableCSP
}

if keys[_KEY_VISIBILITY] || keys[_KEY_VISIBILITY_SHORT] {
baseFlags.Visibility = cliFlags.Visibility
// 判断是否为白名单中的词,以及强制转换内容为大写
if strings.ToUpper(cliFlags.Visibility) != FlareDefine.DEFAULT_VISIBILITY &&
strings.ToUpper(cliFlags.Visibility) != "PRIVATE" {
baseFlags.Visibility = FlareDefine.DEFAULT_VISIBILITY
} else {
baseFlags.Visibility = strings.ToUpper(cliFlags.Visibility)
}
} else {
baseFlags.Visibility = strings.ToUpper(baseFlags.Visibility)
}

if keys[_KEY_ENABLE_OFFLINE] || keys[_KEY_ENABLE_OFFLINE_SHORT] {
baseFlags.EnableOfflineMode = cliFlags.EnableOfflineMode
}

if keys[_KEY_ENABLE_DEPRECATED_NOTICE] || keys[_KEY_ENABLE_DEPRECATED_NOTICE_SHORT] {
baseFlags.EnableDeprecatedNotice = cliFlags.EnableDeprecatedNotice
}

if keys[_KEY_ENABLE_GUIDE] || keys[_KEY_ENABLE_GUIDE_SHORT] {
baseFlags.EnableGuide = cliFlags.EnableGuide
}

if keys[_KEY_ENABLE_EDITOR] || keys[_KEY_ENABLE_EDITOR_SHORT] {
baseFlags.EnableEditor = cliFlags.EnableEditor
}

// Forcibly disable `debug mode` in non-development mode
if strings.ToLower(version.Version) != "dev" {
baseFlags.DebugMode = false
} else {
if keys["D"] || keys["debug"] {
baseFlags.DebugMode = true
}
}

return baseFlags
}
40 changes: 39 additions & 1 deletion cmd/cmd.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,19 @@
package FlareCMD

import (
"fmt"
"log/slog"
"runtime"
"strings"

flags "github.com/spf13/pflag"

FlareData "github.com/soulteary/flare/config/data"
FlareDefine "github.com/soulteary/flare/config/define"
FlareModel "github.com/soulteary/flare/config/model"
FlareState "github.com/soulteary/flare/config/state"
FlareLogger "github.com/soulteary/flare/internal/logger"
"github.com/soulteary/flare/internal/version"
)

func Parse() FlareModel.Flags {
Expand All @@ -24,7 +31,7 @@ func Parse() FlareModel.Flags {
log.Info("当前内容整体可见性为:", slog.String(_KEY_VISIBILITY, flags.Visibility))

if flags.UserIsGenerated {
log.Info("用户未指定 `FLARE_USER`,使用默认用户名", slog.String("username", DEFAULT_USER_NAME))
log.Info("用户未指定 `FLARE_USER`,使用默认用户名", slog.String("username", FlareDefine.DEFAULT_USER_NAME))
} else {
log.Info("应用用户设置为", slog.String("username", flags.User))
}
Expand All @@ -39,3 +46,34 @@ func Parse() FlareModel.Flags {
FlareState.AppFlags = flags
return flags
}

func ExcuteCLI(cliFlags *FlareModel.Flags, options *flags.FlagSet) (exit bool) {
programVersion := GetVersion(false)
if cliFlags.ShowHelp {
fmt.Println(programVersion)
fmt.Println()
fmt.Println("支持命令:")
options.PrintDefaults()
return true
}
if cliFlags.ShowVersion {
fmt.Println(version.Version)
return true
}
return false
}

func GetVersion(echo bool) string {
programVersion := fmt.Sprintf("Flare v%s-%s %s/%s BuildDate=%s", version.Version, strings.ToUpper(version.Commit), runtime.GOOS, runtime.GOARCH, version.BuildDate)
if echo {
log := FlareLogger.GetLogger()
log.Info("Flare - 🏂 Challenge all bookmarking apps and websites directories, Aim to Be a best performance monster.")
log.Info("程序信息:",
slog.String("version", version.Version),
slog.String("commit", strings.ToUpper(version.Commit)),
slog.String("GOGS/ARCH", fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH)),
slog.String("date", version.BuildDate),
)
}
return programVersion
}
79 changes: 79 additions & 0 deletions cmd/cmd_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package FlareCMD_test

import (
"bytes"
"io"
"os"
"testing"

FlareCMD "github.com/soulteary/flare/cmd"
FlareModel "github.com/soulteary/flare/config/model"
"github.com/soulteary/flare/internal/version"
flags "github.com/spf13/pflag"
"github.com/stretchr/testify/assert"
)

func captureOutput(f func()) string {
old := os.Stdout
r, w, _ := os.Pipe()
os.Stdout = w
outC := make(chan string)
go func() {
var buf bytes.Buffer
io.Copy(&buf, r)
outC <- buf.String()
}()
f()
w.Close()
os.Stdout = old
return <-outC
}

func TestExcuteCLI_ShowHelp(t *testing.T) {
cliFlags := &FlareModel.Flags{ShowHelp: true}
options := &flags.FlagSet{}

output := captureOutput(func() {
_ = FlareCMD.ExcuteCLI(cliFlags, options)
})

assert.Contains(t, output, "支持命令:", "应该打印出支持命令")
assert.True(t, FlareCMD.ExcuteCLI(cliFlags, options), "在 ShowHelp 为 true 时,应该返回 true")
}

func TestExcuteCLI_ShowVersion(t *testing.T) {
cliFlags := &FlareModel.Flags{ShowVersion: true}
options := &flags.FlagSet{}

output := captureOutput(func() {
_ = FlareCMD.ExcuteCLI(cliFlags, options)
})

assert.Contains(t, output, version.Version, "应该打印出版本信息")
assert.True(t, FlareCMD.ExcuteCLI(cliFlags, options), "在 ShowVersion 为 true 时,应该返回 true")
}

func TestExcuteCLI_NoFlags(t *testing.T) {
cliFlags := &FlareModel.Flags{}
options := &flags.FlagSet{}

assert.False(t, FlareCMD.ExcuteCLI(cliFlags, options), "当没有任何标志被设置时,应该返回 false")
}

func TestGetVersionEcho(t *testing.T) {
ver := ""
// output := captureOutput(func() {
ver = FlareCMD.GetVersion(true)
// })
assert.Contains(t, ver, version.Version, "应该打印出版本信息")
// assert.Contains(t, output, "Challenge all bookmarking apps and websites directories, Aim to Be a best performance monster.", "应该打印详细信息")
}

func TestGetVersionMute(t *testing.T) {
ver := ""
output := captureOutput(func() {
ver = FlareCMD.GetVersion(false)
})
assert.Contains(t, ver, version.Version, "应该打印出版本信息")
assert.NotContains(t, output, "Challenge all bookmarking apps and websites directories, Aim to Be a best performance monster.", "不应该打印详细信息")
}
13 changes: 0 additions & 13 deletions cmd/define.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,5 @@
package FlareCMD

const (
DEFAULT_PORT = 5005
DEFAULT_ENABLE_GUIDE = true
DEFAULT_ENABLE_DEPRECATED_NOTICE = true
DEFAULT_ENABLE_MINI_REQUEST = false
DEFAULT_DISABLE_LOGIN = true
DEFAULT_ENABLE_OFFLINE = false
DEFAULT_USER_NAME = "flare"
DEFAULT_ENABLE_EDITOR = true
DEFAULT_VISIBILITY = "DEFAULT"
DEFAULT_DISABLE_CSP = false
)

const (
_KEY_PORT = "port"
_KEY_PORT_SHORT = "p"
Expand Down
71 changes: 71 additions & 0 deletions cmd/env.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package FlareCMD

import (
"fmt"

env "github.com/caarlos0/env/v6"

FlareData "github.com/soulteary/flare/config/data"
FlareDefine "github.com/soulteary/flare/config/define"
FlareModel "github.com/soulteary/flare/config/model"
FlareLogger "github.com/soulteary/flare/internal/logger"
)

func InitAccountFromEnvVars(
username string, password string, targetUser *string, targetPass *string, defaultName string,
isUserGenerate *bool, isPassGenerate *bool, disableLogin *bool) {

if username == "" {
*targetUser = defaultName
*isUserGenerate = true
} else {
*isUserGenerate = false
*targetUser = username
}

if password == "" {
*targetPass = FlareData.GenerateRandomString(8)
*isPassGenerate = true
} else {
*isPassGenerate = false
*targetPass = password
}
}

func ParseEnvVars() (stor FlareModel.Flags) {
log := FlareLogger.GetLogger()

// 1. init default values
defaults := FlareDefine.GetDefaultEnvVars()

// 2. overwrite with user input
if err := env.Parse(&defaults); err != nil {
log.Error(fmt.Sprintf("%+v\n", err))
return
}

// 3. update username and password
InitAccountFromEnvVars(
defaults.User,
defaults.Pass,
&stor.User,
&stor.Pass,
FlareDefine.DEFAULT_USER_NAME,
&stor.UserIsGenerated,
&stor.PassIsGenerated,
&stor.DisableLoginMode,
)

// 4. merge
stor.Port = defaults.Port
stor.EnableGuide = defaults.EnableGuide
stor.EnableDeprecatedNotice = defaults.EnableDeprecatedNotice
stor.EnableMinimumRequest = defaults.EnableMinimumRequest
stor.DisableLoginMode = defaults.DisableLoginMode
stor.Visibility = defaults.Visibility
stor.EnableOfflineMode = defaults.EnableOfflineMode
stor.EnableEditor = defaults.EnableEditor
stor.DisableCSP = defaults.DisableCSP

return stor
}
Loading

0 comments on commit e27ed91

Please sign in to comment.