Previous questions

The problem with the previous code was that it did not support command-line arguments, which resulted in a rigid execution of the program. For example, the common one is

The configuration file cannot be read when the executable file and the corresponding configuration file are not in the same directory

Or the above scenario, even though our executables and configuration files are all in the same directory

But there’s no configuration file underneath where we execute the command and that’s not executable.

So the system is very inflexible.

Read command line arguments

package main

import (
   "fmt"
   "os"
)

func main() {
   if len(os.Args) > 0 {
      for index, arg := range os.Args {
         fmt.Printf("args[%d]=%v\n", index, arg)
      }
   }
}
Copy the code

Take a look at the execution result of the program:

Args is an array of strings. The first position is the executable itself, and the second position is the parameters

With this foundation, it’s easy to modify our code

Modify the framework

First we add a filePath parameter to the initialization file

Func Init(filePath string) error {// If len(filePath) == 0 { Viper.setconfigname ("config") // The name of the configuration file viper.setConfigType ("yaml") // The extension of the configuration file Viper.addconfigpath (".")} else {viper.setConfigFile (filePath)} err := viper.ReadInConfig() if err ! = nil {fmt.Println("viper init failed:", err) return err} if err := per.unmarshal (Config); err ! = nil { fmt.Println("viper Unmarshal err", Err)} per.watchConfig () per.onConfigChange (func(in fsnotify.event) {fmt.println (" Config file has been modified ")}) return err}Copy the code

Then read the parameters at the beginning of main

Func main() {filePath := "" if len(os.args) >= 2 {filePath = os.args [1]} // Load the configuration file if err := setting.init (filePath); err ! = nil { fmt.Printf("init settings failed:%s \n", err) return }Copy the code

More standard support for command-line arguments

Although the above writing method solved the pain point, but it seems not quite standard, most of the time we use other people’s programs are -t-p and so on, here we also need to be professional to recommend the use of flag package to solve our problems, the code is very simple.

So let’s write main

Flag. StringVar(&filepath, "file", "", Flag.parse () // Load the configuration file if err := setting.init (filePath); err ! Printf("init Settings failed:%s \n", err) return} if err := logger.init (setting.config.logconfig);  err ! = nil { fmt.Printf("init settings failed:%s \n", err) return }Copy the code

Then look at the actual results:

This is the end of a nearly full-featured Web Server development framework.

The source address