summaryrefslogtreecommitdiff
path: root/cmd/lectio-web/main.go
blob: 327496a1ecc4b833c54c4bbd6540a121262cc9e3 (plain) (blame)
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
}