This repository has been archived by the owner on Mar 22, 2023. It is now read-only.
/
start.go
133 lines (106 loc) · 2.88 KB
/
start.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package helloworld
import (
"encoding/json"
"encoding/xml"
"fmt"
"io/ioutil"
"log"
"os"
"strings"
"time"
"github.com/BurntSushi/toml"
flag "github.com/spf13/pflag"
"golift.io/version"
yaml "gopkg.in/yaml.v3"
)
// Flags defines our application's CLI arguments.
type Flags struct {
VersionReq bool
ConfigFile string
}
// Config defines our applications's config file parameters.
type Config struct {
Worlds int `json:"worlds" xml:"worlds" toml:"worlds" yaml:"worlds"`
Hellos int `json:"hellos" xml:"hellos" toml:"hellos" yaml:"hellos"`
}
// HelloWorld is the main application struct.
type HelloWorld struct {
Flag *flag.FlagSet
*Flags
*Config
}
// Binary is the app name.
const Binary = "hello-world"
const (
defaultConfFile = "/etc/hello-world/helloworld.conf"
defaultWorlds = 2
defaultHellos = 1
)
// Start begins the application from a CLI.
// Parses flags, parses config and executes Run().
func Start() error {
hw := &HelloWorld{
Flags: &Flags{VersionReq: false, ConfigFile: defaultConfFile},
Flag: flag.NewFlagSet(Binary, flag.ExitOnError),
}
log.SetFlags(log.LstdFlags)
hw.ParseFlags(os.Args[1:])
if hw.VersionReq {
fmt.Println(version.Print(Binary))
return nil // don't run anything else w/ version request.
}
if err := hw.GetConfig(); err != nil {
hw.Flag.Usage()
return err
}
return hw.Run()
}
// ParseFlags runs the parser for CLI arguments.
func (u *HelloWorld) ParseFlags(args []string) {
u.Flag.Usage = func() {
fmt.Printf("Usage: %s [--config=filepath] [--version]", Binary)
u.Flag.PrintDefaults()
}
u.Flag.StringVarP(&u.ConfigFile, "config", "c", defaultConfFile, "Config File (TOML Format)")
u.Flag.BoolVarP(&u.VersionReq, "version", "v", false, "Print the version and exit")
_ = u.Flag.Parse(args)
}
// GetConfig parses and returns our configuration data.
// Supports any format for config file: xml, yaml, json, toml.
func (u *HelloWorld) GetConfig() error {
// Preload our defaults.
u.Config = &Config{
Hellos: defaultHellos,
Worlds: defaultWorlds,
}
log.Printf("Loading Configuration File: %s", u.ConfigFile)
buf, err := ioutil.ReadFile(u.ConfigFile)
switch {
case err != nil:
return fmt.Errorf("ioutil.ReadFile: %w", err)
case strings.Contains(u.ConfigFile, ".json"):
err = json.Unmarshal(buf, u.Config)
case strings.Contains(u.ConfigFile, ".xml"):
err = xml.Unmarshal(buf, u.Config)
case strings.Contains(u.ConfigFile, ".yaml"):
err = yaml.Unmarshal(buf, u.Config)
default:
err = toml.Unmarshal(buf, u.Config)
}
if err != nil {
return fmt.Errorf("unmarshalling: %w", err)
}
return nil
}
// Run starts doing things.
func (u *HelloWorld) Run() error {
log.Printf("[INFO] Hello World v%v Starting Up! PID: %d", version.Version, os.Getpid())
time.Sleep(time.Second)
for i := 1; i <= u.Config.Hellos; i++ {
fmt.Println(i, "hello")
}
for i := 1; i <= u.Config.Worlds; i++ {
fmt.Println(i, "world")
}
return nil
}