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
|
// Command lectio-web serves lectio's browser reading UI.
package main
import (
"flag"
"fmt"
"io"
"os"
"github.com/lukaszkasprzak/lectio/internal/config"
"github.com/lukaszkasprzak/lectio/internal/web"
)
const helpText = `lectio-web — browser daily liturgy reader (Polish + 4 versions)
Usage:
lectio-web [flags]
Flags:
-p, --port N port (overrides web_port; 0 = auto)
-o, --offline cache/sigla only, no network
-l, --lectionary WHICH new|trad (trad -> traditional)
-v, --version print the version and exit
-h, --help this help
Flags override config. Exit codes: 0 ok, 1 runtime error, 2 usage error.
`
func main() {
os.Exit(run(os.Args[1:], os.Stdout, os.Stderr))
}
// run is lectio-web's testable entry point: parse args, validate, load
// config, apply overrides, and launch the server. Returns a process exit
// code.
func run(args []string, stdout, stderr io.Writer) int {
if wantsHelp(args) {
fmt.Fprint(stdout, helpText)
return 0
}
if wantsVersion(args) {
fmt.Fprintln(stdout, "lectio-web "+config.Version)
return 0
}
cfg, err := config.Load()
if err != nil {
fmt.Fprintln(stderr, "lectio-web:", err)
return 1
}
var offline bool
var port int
var lectionary string
fs := flag.NewFlagSet("lectio-web", flag.ContinueOnError)
fs.SetOutput(stderr)
fs.Usage = func() { fmt.Fprint(stderr, helpText) }
fs.IntVar(&port, "p", cfg.WebPort, "port (overrides web_port; 0 = auto)")
fs.IntVar(&port, "port", cfg.WebPort, "port (overrides web_port; 0 = auto)")
fs.BoolVar(&offline, "o", cfg.Offline, "cache/sigla only, no network")
fs.BoolVar(&offline, "offline", cfg.Offline, "cache/sigla only, no network")
fs.StringVar(&lectionary, "l", "", "new|trad")
fs.StringVar(&lectionary, "lectionary", "", "new|trad")
if err := fs.Parse(args); err != nil {
return 2
}
if fs.NArg() > 0 {
fmt.Fprintf(stderr, "lectio-web: unexpected argument %q; see 'lectio-web -h'\n", fs.Arg(0))
return 2
}
lectionary, err = normalizeLectionary(lectionary)
if err != nil {
fmt.Fprintln(stderr, "lectio-web:", err)
return 2
}
cfg.WebPort = port
cfg.Offline = offline
if lectionary != "" {
cfg.Lectionary = lectionary
}
if err := web.Run(cfg); err != nil {
fmt.Fprintln(stderr, err)
return 1
}
return 0
}
// wantsHelp reports whether -h/--help appears anywhere in args.
func wantsHelp(args []string) bool {
for _, a := range args {
if a == "-h" || a == "--help" {
return true
}
}
return false
}
// wantsVersion reports whether -v/--version appears anywhere in args.
func wantsVersion(args []string) bool {
for _, a := range args {
if a == "-v" || a == "--version" {
return true
}
}
return false
}
// normalizeLectionary maps -l/--lectionary's accepted spellings via
// config.NormalizeLectionary; "" (flag not given) passes through unchanged.
func normalizeLectionary(lectionary string) (string, error) {
if lectionary == "" {
return "", nil
}
v, ok := config.NormalizeLectionary(lectionary)
if !ok {
return "", fmt.Errorf("invalid --lectionary %q (want new|trad)", lectionary)
}
return v, nil
}
|