Skip to content

Commit

Permalink
add option enable-default-config, add log
Browse files Browse the repository at this point in the history
  • Loading branch information
lai323 committed Jul 8, 2021
1 parent 6fbd4f6 commit 7f2dca8
Show file tree
Hide file tree
Showing 3 changed files with 212 additions and 20 deletions.
12 changes: 8 additions & 4 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import (
)

var (
initWithOutConfig bool
rootCmd = &cobra.Command{
initWithOutConfig bool
enableDefaultConfig bool
initWithOutLog bool
rootCmd = &cobra.Command{
Use: "readygo module_name out_dir",
Short: "create empty project with cobra and spf13",
Args: func(cmd *cobra.Command, args []string) error {
Expand All @@ -24,7 +26,7 @@ var (
if len(args) > 1 {
outdir = args[1]
}
err := generate.InitCli(args[0], outdir, !initWithOutConfig)
err := generate.InitCli(args[0], outdir, initWithOutConfig, enableDefaultConfig, initWithOutLog)
if err != nil {
fmt.Printf("error: %s\n", err.Error())
}
Expand All @@ -40,5 +42,7 @@ func Execute() {
}

func init() {
rootCmd.PersistentFlags().BoolVar(&initWithOutConfig, "without-config", false, "Not use configuration files")
rootCmd.PersistentFlags().BoolVar(&initWithOutConfig, "with-out-config", false, "Not use configuration files")
rootCmd.PersistentFlags().BoolVar(&initWithOutLog, "with-out-log", false, "Not generate logger")
rootCmd.PersistentFlags().BoolVar(&enableDefaultConfig, "enable-default-config", false, "generate default config in XDG_CONFIG_HOME, if config file not exist")
}
214 changes: 200 additions & 14 deletions generate/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ var (
tmplNameMain = "main"
tmplNameRoot = "root"
tmplNameConfig = "config"
tmplNameLog = "log"
)

func init() {
Expand All @@ -23,19 +24,25 @@ func init() {
tmplNameMain: tmplTextMain,
tmplNameRoot: tmplTextRoot,
tmplNameConfig: tmplTextConfig,
tmplNameLog: tmplTextLog,
}
for name, text := range tmpls {
template.Must(tmpl.New(name).Parse(text))
}
}

type tmplVarRoot struct {
Module string
WithConfig bool
Module string
WithConfig bool
EnableDefaultConfig bool
}

type tmplVarConfig struct {
Module string
Module string
EnableDefaultConfig bool
}

type tmplVarLog struct {
}

type tmplVarMain struct {
Expand Down Expand Up @@ -68,41 +75,53 @@ func getProjectDir(module, outdir string) (string, error) {
return projectDir, nil
}

func InitCli(module, outdir string, initWithConfig bool) error {
func InitCli(module, outdir string, initWithOutConfig, enableDefaultConfig, initWithOutLog bool) error {
projectDir, err := getProjectDir(module, outdir)
if err != nil {
return err
}

var (
cmdDir = fmt.Sprintf("%s/cmd", projectDir)
configDir = fmt.Sprintf("%s/config", projectDir)
filePathMain = fmt.Sprintf("%s/main.go", projectDir)
filePathRoot = fmt.Sprintf("%s/root.go", cmdDir)
filePathCocnfig = fmt.Sprintf("%s/config.go", configDir)
cmdDir = fmt.Sprintf("%s/cmd", projectDir)
configDir = fmt.Sprintf("%s/config", projectDir)
logDir = fmt.Sprintf("%s/logger", projectDir)
filePathMain = fmt.Sprintf("%s/main.go", projectDir)
filePathRoot = fmt.Sprintf("%s/root.go", cmdDir)
filePathConfig = fmt.Sprintf("%s/config.go", configDir)
filePathLog = fmt.Sprintf("%s/logger.go", logDir)
)
err = mkdirAll(cmdDir)
if err != nil {
return err
}
if initWithConfig {
if !initWithOutConfig {
err = mkdirAll(configDir)
if err != nil {
return err
}
}
if !initWithOutLog {
err = mkdirAll(logDir)
if err != nil {
return err
}
}

tocreate := map[string]string{
tmplNameMain: filePathMain,
tmplNameRoot: filePathRoot,
}
tocreateData := map[string]interface{}{
tmplNameMain: tmplVarMain{module},
tmplNameRoot: tmplVarRoot{module, initWithConfig},
tmplNameRoot: tmplVarRoot{module, !initWithOutConfig, enableDefaultConfig},
}
if initWithConfig {
tocreate[tmplNameConfig] = filePathCocnfig
tocreateData[tmplNameConfig] = tmplVarConfig{module}
if !initWithOutConfig {
tocreate[tmplNameConfig] = filePathConfig
tocreateData[tmplNameConfig] = tmplVarConfig{module, enableDefaultConfig}
}
if !initWithOutLog {
tocreate[tmplNameLog] = filePathLog
tocreateData[tmplNameLog] = tmplVarLog{}
}
for tmplname, filepath := range tocreate {
f, err := os.Create(filepath)
Expand Down Expand Up @@ -175,8 +194,10 @@ import (
{{- .Module }}/config"
{{- end }}
{{- if .WithConfig }}
{{- if .EnableDefaultConfig }}
"github.com/spf13/afero"
{{- end }}
{{- end }}
"github.com/spf13/cobra"
{{- if .WithConfig }}
"github.com/spf13/viper"
Expand Down Expand Up @@ -217,14 +238,20 @@ func Execute() {
{{- if .WithConfig }}
func init() {
cobra.OnInitialize(initConfig)
{{- if .EnableDefaultConfig }}
rootCmd.PersistentFlags().StringVar(&configPath, "config", "", fmt.Sprintf("config file (default is %s)", config.DefaultConfigPath))
{{- end }}
rootCmd.PersistentFlags().String("var", "ViperTest var", "use Viper for configuration")
viper.BindPFlag("var", rootCmd.PersistentFlags().Lookup("var"))
rootCmd.AddCommand(subCmd)
}
func initConfig() {
{{- if .EnableDefaultConfig }}
err := config.InitConfig(afero.NewOsFs(), configPath)
{{- else }}
err := config.InitConfig(configPath)
{{- end }}
if err != nil {
panic(err)
}
Expand All @@ -240,6 +267,7 @@ func init() {
var tmplTextConfig = `
package config
{{- if .EnableDefaultConfig }}
import (
"fmt"
"log"
Expand Down Expand Up @@ -339,4 +367,162 @@ func InitConfig(fs afero.Fs, configPath string) error {
}
return viper.ReadInConfig()
}
{{- else}}
import (
"fmt"
"os"
"github.com/spf13/viper"
)
func InitConfig(configPath string) error {
if _, err := os.Stat(configPath); err != nil {
if os.IsNotExist(err) {
return fmt.Errorf("InitConfig error: config file (%s) not exist", configPath)
}
return fmt.Errorf("InitConfig error: %s", err.Error())
}
viper.SetConfigFile(configPath)
if err := viper.ReadInConfig(); err != nil {
return fmt.Errorf("InitConfig error: %s", err.Error())
}
return nil
}
{{- end }}
`
var tmplTextLog = `
package logger
import (
"fmt"
"io"
"os"
"path"
"time"
"github.com/lestrrat/go-file-rotatelogs"
"github.com/rifflock/lfshook"
"github.com/sirupsen/logrus"
"github.com/spf13/viper"
)
func NewLoggerByConfig() (*logrus.Logger, error) {
level := viper.GetString("log.level")
stdout := viper.GetBool("log.stdout")
format := viper.GetString("log.format")
logdir := viper.GetString("log.logdir")
logfile := viper.GetString("log.logfile")
if logdir == "" {
logdir = "./log"
}
if logfile == "" {
logfile = "log"
}
fmt.Println(level, stdout, format, logdir, logfile)
return NewLogger(level, format, stdout, logdir, logfile)
}
func newloggerErr(format string, a ...interface{}) error {
return fmt.Errorf("NewLogger error: %s", fmt.Sprintf(format, a...))
}
func NewLogger(loglevel, format string, stdout bool, logdir, logfile string) (*logrus.Logger, error) {
var logger = logrus.New()
var level = logrus.DebugLevel
switch loglevel {
case "panic":
level = logrus.PanicLevel
case "fatal":
level = logrus.FatalLevel
case "error":
level = logrus.ErrorLevel
case "warn":
level = logrus.WarnLevel
case "info":
level = logrus.InfoLevel
case "debug":
level = logrus.DebugLevel
case "trace":
level = logrus.TraceLevel
default:
return logger, newloggerErr("NewLogger error log level not allow: %s allow: panic fatal error warn info debug trace, current:", loglevel)
}
logger.SetLevel(level)
fileSrc, err := os.OpenFile(os.DevNull, os.O_APPEND|os.O_WRONLY, os.ModeAppend)
if err != nil {
return logger, newloggerErr(err.Error())
}
var src io.Writer
if stdout {
stdoutSrc := os.Stdout
src = io.MultiWriter(fileSrc, stdoutSrc)
} else {
src = io.MultiWriter(fileSrc)
}
logger.SetOutput(src)
logger.SetFormatter(getformatter(format))
logger.AddHook(getLogHook(format, logdir, logfile))
return logger, nil
}
func getformatter(f string) logrus.Formatter {
switch f {
case "text":
return &logrus.TextFormatter{
ForceColors: true,
FullTimestamp: true,
}
case "text_disable_fulltimestamp":
return &logrus.TextFormatter{
ForceColors: true,
FullTimestamp: false,
}
case "json":
fallthrough
default:
return &logrus.JSONFormatter{}
}
}
func getLogHook(format, logdir, logfile string) *lfshook.LfsHook {
logWriter, _ := getLogWriter(logdir, logfile)
writeMap := lfshook.WriterMap{
logrus.TraceLevel: logWriter,
logrus.InfoLevel: logWriter,
logrus.FatalLevel: logWriter,
logrus.DebugLevel: logWriter,
logrus.WarnLevel: logWriter,
logrus.ErrorLevel: logWriter,
logrus.PanicLevel: logWriter,
}
return lfshook.NewHook(writeMap, getformatter(format))
}
func getLogWriter(logdir, logfile string) (*rotatelogs.RotateLogs, error) {
if _, err := os.Stat(logdir); err != nil {
if os.IsNotExist(err) {
err := os.Mkdir(logdir, os.ModePerm)
if err != nil {
return nil, newloggerErr("create log dir (%s) error %s", logdir, err.Error())
}
}
return nil, newloggerErr(err.Error())
}
filepath := path.Join(logdir, logfile)
logWriter, err := rotatelogs.New(
filepath+".%Y%m%d.log",
rotatelogs.WithLinkName(filepath),
rotatelogs.WithMaxAge(7*24*time.Hour),
rotatelogs.WithRotationTime(24*time.Hour),
)
if err != nil {
return nil, newloggerErr(err.Error())
}
return logWriter, nil
}
`
6 changes: 4 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ Usage:
readygo module_name out_dir [flags]
Flags:
-h, --help help for readygo
--without-config Not use configuration files
--enable-default-config generate default config in XDG_CONFIG_HOME, if config file not exist
-h, --help help for readygo
--with-out-config Not use configuration files
--with-out-log Not generate logger
```

0 comments on commit 7f2dca8

Please sign in to comment.