cat / 012
clone

a spreadsheet for the terminal: lotus 1-2-3 looks, google sheets keys and formulas, one go binary

Register 012 serve's settings; keep serve's entry points compiling

Dami committed 446a78d
serve-listen, serve-authorized-keys, serve-host-key,
serve-idle-timeout and serve-max-sessions join the registry with number,
duration and address kinds. jev.LoadConfig stays as an
environment-only reader and telemetryFlags reads through the config,
for 012 serve until it takes its settings from the config.
commit
446a78d920b98bb9e1ff565a32f4dd2a72230f02
parent
7e69e7501d42c4e050f00871cdfe1ec98f21db6f
author
Dami <dami.etoile@gmail.com>
10 files changed, +154 -16
Mcmd/012/telemetry.go16+++++++++
Mdocs/config.md52++++++++++++++++++++++++++++++
Minternal/config/config.go13+++++++
Minternal/config/config_test.go14++++++++
Minternal/config/registry.go36+++++++++++++++++++--
Minternal/jev/apikey.go14++++++++
Minternal/ui/graphics.go10+++---
Minternal/ui/model.go3+-
Minternal/ui/prefs.go8++--
Minternal/ui/themepicker.go4+-
M cmd/012/telemetry.go +16 -0
M docs/config.md +52 -0
M internal/config/config.go +13 -0
M internal/config/config_test.go +14 -0
M internal/config/registry.go +33 -3
@@ -17,6 +17,7 @@ import (
1717 "net/url"1818 "strconv"1919 "strings"20+ "time"2021 )2122 2223 // Kind is an option's type.
@@ -28,11 +29,14 @@ const (
2829 Enum // one of Option.Values2930 Path // a file path; ~ is the home directory3031 URL31- Command // a program and its arguments, run without a shell32+ Command // a program and its arguments, run without a shell33+ Int // a whole number, at least 134+ Duration // e.g. 30m or 1h30m; 0 for never35+ Address // host:port3236 )3337 3438 func (k Kind) String() string {35- return [...]string{"text", "true or false", "one of", "path", "URL", "command"}[k]39+ return [...]string{"text", "true or false", "one of", "path", "URL", "command", "number", "duration", "host:port"}[k]3640 }3741 3842 // Option is one setting.
@@ -60,11 +64,12 @@ const (
6064 GroupAppearance = "Appearance"6165 GroupJEV = "JEV functions"6266 GroupTelemetry = "Telemetry"67+ GroupServe = "012 serve"6368 GroupFiles = "Config files"6469 )6570 6671 // Groups is the order groups are listed in.67-var Groups = []string{GroupAppearance, GroupJEV, GroupTelemetry, GroupFiles}72+var Groups = []string{GroupAppearance, GroupJEV, GroupTelemetry, GroupServe, GroupFiles}6873 6974 // Options is every setting. Add an option here and read it with7075 // Config.String, Bool or List; parsing, `012 config`, docs/config.md
@@ -107,6 +112,19 @@ var Options = []Option{
107112 "The other OTEL_* variables still apply.",108113 Redact: redactURL},109114 115+ {Name: "serve-listen", Kind: Address, Group: GroupServe, Default: "127.0.0.1:2312",116+ Desc: "The address 012 serve listens on. Anything but the loopback address lets other machines " +117+ "reach it (with an authorized key). See docs/ssh.md."},118+ {Name: "serve-authorized-keys", Kind: Path, Group: GroupServe, Default: "~/.ssh/authorized_keys",119+ Desc: "The public keys allowed to log in to 012 serve, in OpenSSH's authorized_keys format."},120+ {Name: "serve-host-key", Kind: Path, Group: GroupServe,121+ Desc: "012 serve's private host key, generated when missing; " +122+ "ssh_host_ed25519_key in the config directory when empty."},123+ {Name: "serve-idle-timeout", Kind: Duration, Group: GroupServe, Default: "30m",124+ Desc: "End a 012 serve session that has had no input for this long; 0 never does."},125+ {Name: "serve-max-sessions", Kind: Int, Group: GroupServe, Default: "8",126+ Desc: "How many 012 serve sessions may run at once; more are turned away."},127+110128 {Name: "config-file", Kind: Path, Group: GroupFiles, Repeat: true,111129 Desc: "Read another config file after this one, relative to this file's directory. " +112130 "A leading `?` makes it optional: no warning when it doesn't exist."},
@@ -154,6 +172,18 @@ func (o *Option) validate(v string) error {
154172 if _, err := SplitCommand(v); err != nil {155173 return err156174 }175+ case Int:176+ if n, err := strconv.Atoi(v); err != nil || n < 1 {177+ return fmt.Errorf("%q isn't a whole number of at least 1", v)178+ }179+ case Duration:180+ if d, err := time.ParseDuration(v); err != nil || d < 0 {181+ return fmt.Errorf("%q isn't a duration like 30m or 1h", v)182+ }183+ case Address:184+ if _, _, err := net.SplitHostPort(v); err != nil {185+ return fmt.Errorf("%q isn't host:port", v)186+ }157187 }158188 if o.Check != nil {159189 return o.Check(v)
M internal/jev/apikey.go +14 -0
M internal/ui/graphics.go +5 -5
M internal/ui/model.go +1 -2
M internal/ui/prefs.go +4 -4
M internal/ui/themepicker.go +2 -2