Skip to content

Commit 384a108

Browse files
authored
Merge pull request #91 from mutablelogic/v5
V5
2 parents 2d6d3ee + 04cd45f commit 384a108

File tree

18 files changed

+143
-142
lines changed

18 files changed

+143
-142
lines changed

cmd.go

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ import (
1313

1414
// Cmd represents the command line interface context
1515
type Cmd interface {
16+
// Run the command
17+
Run() error
18+
1619
// Return the context
1720
Context() context.Context
1821

@@ -31,11 +34,6 @@ type Cmd interface {
3134

3235
type DebugLevel uint
3336

34-
type CmdOffsetLimit struct {
35-
Offset uint64 `name:"offset" help:"List item offset"`
36-
Limit *uint64 `name:"limit" help:"List item limit"`
37-
}
38-
3937
///////////////////////////////////////////////////////////////////////////////
4038
// GLOBALS
4139

cmd/server/main.go

Lines changed: 8 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,21 @@
11
package main
22

33
import (
4+
"fmt"
45
"os"
5-
"os/user"
6-
"path/filepath"
76

87
// Packages
9-
kong "github.com/alecthomas/kong"
10-
server "github.com/mutablelogic/go-server"
118
auth "github.com/mutablelogic/go-server/pkg/auth/cmd"
12-
auth_schema "github.com/mutablelogic/go-server/pkg/auth/schema"
139
certmanager "github.com/mutablelogic/go-server/pkg/cert/cmd"
14-
cert_schema "github.com/mutablelogic/go-server/pkg/cert/schema"
10+
cmd "github.com/mutablelogic/go-server/pkg/cmd"
1511
pgmanager "github.com/mutablelogic/go-server/pkg/pgmanager/cmd"
16-
pgmanager_schema "github.com/mutablelogic/go-server/pkg/pgmanager/schema"
1712
pgqueue "github.com/mutablelogic/go-server/pkg/pgqueue/cmd"
18-
pgqueue_schema "github.com/mutablelogic/go-server/pkg/pgqueue/schema"
1913
)
2014

2115
///////////////////////////////////////////////////////////////////////////////
2216
// TYPES
2317

2418
type CLI struct {
25-
Globals
2619
ServiceCommands
2720
pgmanager.DatabaseCommands
2821
pgmanager.SchemaCommands
@@ -47,57 +40,15 @@ type CLI struct {
4740
func main() {
4841
// Parse command-line flags
4942
var cli CLI
50-
kong := kong.Parse(&cli,
51-
kong.Name(execName()),
52-
kong.Description("command-line tool"),
53-
kong.UsageOnError(),
54-
kong.ConfigureHelp(kong.HelpOptions{Compact: true}),
55-
kong.Vars{
56-
"HOST": hostName(),
57-
"USER": userName(),
58-
"CERT_PREFIX": cert_schema.APIPrefix,
59-
"PG_PREFIX": pgmanager_schema.APIPrefix,
60-
"AUTH_PREFIX": auth_schema.APIPrefix,
61-
"QUEUE_PREFIX": pgqueue_schema.APIPrefix,
62-
},
63-
)
6443

65-
// Create the app
66-
app, err := NewApp(cli.Globals, kong.Model.Vars())
44+
app, err := cmd.New(&cli, "go-server command-line tool")
6745
if err != nil {
68-
kong.FatalIfErrorf(err)
46+
fmt.Fprintln(os.Stderr, err)
47+
os.Exit(-1)
6948
}
70-
defer app.Close()
7149

72-
// Run
73-
kong.BindTo(app, (*server.Cmd)(nil))
74-
kong.FatalIfErrorf(kong.Run())
75-
}
76-
77-
///////////////////////////////////////////////////////////////////////////////
78-
// PRIVATE METHODS
79-
80-
func hostName() string {
81-
name, err := os.Hostname()
82-
if err != nil {
83-
panic(err)
84-
}
85-
return name
86-
}
87-
88-
func userName() string {
89-
user, err := user.Current()
90-
if err != nil {
91-
panic(err)
92-
}
93-
return user.Username
94-
}
95-
96-
func execName() string {
97-
// The name of the executable
98-
name, err := os.Executable()
99-
if err != nil {
100-
panic(err)
50+
if err := app.Run(); err != nil {
51+
fmt.Fprintln(os.Stderr, err)
52+
os.Exit(-2)
10153
}
102-
return filepath.Base(name)
10354
}

cmd/server/service.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package main
33
import (
44
"context"
55
"errors"
6+
"fmt"
67
"net/http"
78
"os"
89

@@ -17,6 +18,7 @@ import (
1718
provider "github.com/mutablelogic/go-server/pkg/provider"
1819
ref "github.com/mutablelogic/go-server/pkg/ref"
1920
types "github.com/mutablelogic/go-server/pkg/types"
21+
version "github.com/mutablelogic/go-server/pkg/version"
2022

2123
// Plugins
2224
auth "github.com/mutablelogic/go-server/pkg/auth/config"
@@ -201,6 +203,8 @@ func (cmd *ServiceRunCommand) Run(app server.Cmd) error {
201203
return err
202204
}
203205

206+
fmt.Println("go-server", version.Version())
207+
204208
// Run the provider
205209
return provider.Run(app.Context())
206210
}

pkg/auth/manager_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ func Test_Auth_002(t *testing.T) {
301301

302302
// Create a new user
303303
user, err := manager.CreateUser(context.TODO(), schema.UserMeta{
304-
Name: types.StringPtr("test"),
304+
Name: types.StringPtr("test20"),
305305
Desc: types.StringPtr("test user"),
306306
Scope: []string{},
307307
Meta: map[string]any{},
@@ -312,7 +312,7 @@ func Test_Auth_002(t *testing.T) {
312312

313313
// Create a new user and archive
314314
archived, err := manager.CreateUser(context.TODO(), schema.UserMeta{
315-
Name: types.StringPtr("test2"),
315+
Name: types.StringPtr("test21"),
316316
Desc: types.StringPtr("test user"),
317317
Scope: []string{},
318318
Meta: map[string]any{},
@@ -372,7 +372,7 @@ func Test_Auth_002(t *testing.T) {
372372
t.Run("GetToken3", func(t *testing.T) {
373373
// Create a new user
374374
user, err := manager.CreateUser(context.TODO(), schema.UserMeta{
375-
Name: types.StringPtr("test3"),
375+
Name: types.StringPtr("test22"),
376376
Desc: types.StringPtr("test user"),
377377
Scope: []string{},
378378
Meta: map[string]any{},
@@ -498,7 +498,7 @@ func Test_Auth_003(t *testing.T) {
498498

499499
// Create a new user
500500
user, err := manager.CreateUser(context.TODO(), schema.UserMeta{
501-
Name: types.StringPtr("test"),
501+
Name: types.StringPtr("test30"),
502502
Desc: types.StringPtr("test user"),
503503
Scope: []string{},
504504
Meta: map[string]any{},

pkg/cert/cmd/name.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ type NameCommands struct {
2222
}
2323

2424
type NameListCommand struct {
25-
server.CmdOffsetLimit
25+
schema.NameListRequest
2626
}
2727

2828
type NameMeta struct {

cmd/server/app.go renamed to pkg/cmd/app.go

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
package main
1+
package cmd
22

33
import (
44
"context"
55
"fmt"
66
"net/url"
77
"os"
88
"os/signal"
9+
"os/user"
910
"path/filepath"
1011
"syscall"
1112

@@ -20,46 +21,60 @@ import (
2021
///////////////////////////////////////////////////////////////////////////////
2122
// TYPES
2223

23-
type Globals struct {
24+
type app struct {
2425
Endpoint string `env:"ENDPOINT" default:"http://localhost/" help:"Service endpoint"`
2526
Debug bool `help:"Enable debug output"`
2627
Trace bool `help:"Enable trace output"`
2728

28-
vars kong.Vars `kong:"-"` // Variables for kong
29+
kong *kong.Context `kong:"-"` // Kong parser
30+
vars kong.Vars `kong:"-"` // Variables for kong
2931
ctx context.Context
3032
cancel context.CancelFunc
3133
}
3234

33-
var _ server.Cmd = (*Globals)(nil)
35+
var _ server.Cmd = (*app)(nil)
3436

3537
///////////////////////////////////////////////////////////////////////////////
3638
// LIFECYCLE
3739

38-
func NewApp(app Globals, vars kong.Vars) (*Globals, error) {
39-
// Set the vars
40-
app.vars = vars
40+
func New(commands any, description string) (server.Cmd, error) {
41+
app := new(app)
42+
43+
app.kong = kong.Parse(commands,
44+
kong.Name(execName()),
45+
kong.Description(description),
46+
kong.UsageOnError(),
47+
kong.ConfigureHelp(kong.HelpOptions{Compact: true}),
48+
kong.Embed(app),
49+
kong.Vars{
50+
"HOST": hostName(),
51+
"USER": userName(),
52+
},
53+
)
4154

4255
// Create the context
4356
// This context is cancelled when the process receives a SIGINT or SIGTERM
4457
app.ctx, app.cancel = signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
4558

4659
// Return the app
47-
return &app, nil
60+
return app, nil
4861
}
4962

50-
func (app *Globals) Close() error {
63+
func (app *app) Run() error {
64+
app.kong.BindTo(app, (*server.Cmd)(nil))
65+
err := app.kong.Run()
5166
app.cancel()
52-
return nil
67+
return err
5368
}
5469

5570
///////////////////////////////////////////////////////////////////////////////
5671
// PUBLIC METHODS
5772

58-
func (app *Globals) Context() context.Context {
73+
func (app *app) Context() context.Context {
5974
return app.ctx
6075
}
6176

62-
func (app *Globals) GetDebug() server.DebugLevel {
77+
func (app *app) GetDebug() server.DebugLevel {
6378
if app.Debug {
6479
return server.Debug
6580
}
@@ -69,7 +84,7 @@ func (app *Globals) GetDebug() server.DebugLevel {
6984
return server.None
7085
}
7186

72-
func (app *Globals) GetEndpoint(paths ...string) *url.URL {
87+
func (app *app) GetEndpoint(paths ...string) *url.URL {
7388
url, err := url.Parse(app.Endpoint)
7489
if err != nil {
7590
return nil
@@ -82,7 +97,7 @@ func (app *Globals) GetEndpoint(paths ...string) *url.URL {
8297
return url
8398
}
8499

85-
func (app *Globals) GetClientOpts() []client.ClientOpt {
100+
func (app *app) GetClientOpts() []client.ClientOpt {
86101
opts := []client.ClientOpt{}
87102

88103
// Trace mode
@@ -104,3 +119,31 @@ func (app *Globals) GetClientOpts() []client.ClientOpt {
104119
// Return options
105120
return opts
106121
}
122+
123+
///////////////////////////////////////////////////////////////////////////////
124+
// PRIVATE METHODS
125+
126+
func hostName() string {
127+
name, err := os.Hostname()
128+
if err != nil {
129+
panic(err)
130+
}
131+
return name
132+
}
133+
134+
func userName() string {
135+
user, err := user.Current()
136+
if err != nil {
137+
panic(err)
138+
}
139+
return user.Username
140+
}
141+
142+
func execName() string {
143+
// The name of the executable
144+
name, err := os.Executable()
145+
if err != nil {
146+
panic(err)
147+
}
148+
return filepath.Base(name)
149+
}

pkg/logger/term.go

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,9 @@ const (
5454
// PUBLIC METHODS
5555

5656
func (h *TermHandler) Handle(ctx context.Context, r slog.Record) error {
57-
level := r.Level.String() + ":"
58-
label := ref.Label(ctx) + ":"
57+
var parts []any
58+
59+
level := r.Level.String()
5960
switch r.Level {
6061
case slog.LevelDebug:
6162
level = colorize(darkGray, level)
@@ -66,6 +67,12 @@ func (h *TermHandler) Handle(ctx context.Context, r slog.Record) error {
6667
case slog.LevelError:
6768
level = colorize(lightRed, level)
6869
}
70+
parts = append(parts, level+":")
71+
72+
label := ref.Label(ctx)
73+
if label != "" {
74+
parts = append(parts, label+":")
75+
}
6976

7077
// Gather attributes
7178
var data []byte
@@ -75,14 +82,10 @@ func (h *TermHandler) Handle(ctx context.Context, r slog.Record) error {
7582
data = data_
7683
}
7784

85+
parts = append(parts, colorize(white, r.Message), string(data))
86+
7887
// Print the message, return any errors
79-
fmt.Fprintln(h.Writer,
80-
colorize(lightGray, r.Time.Format(timeFormat)),
81-
level,
82-
label,
83-
colorize(white, r.Message),
84-
string(data),
85-
)
88+
fmt.Fprintln(h.Writer, parts...)
8689
return nil
8790
}
8891

pkg/parser/parser.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func New(plugins ...server.Plugin) (*parser, error) {
3232
name := plugin.Name()
3333
if _, exists := p.meta[name]; exists {
3434
return nil, httpresponse.ErrConflict.Withf("duplicate plugin: %q", name)
35-
} else if meta, err := meta.New(plugin, name); err != nil {
35+
} else if meta, err := meta.New(plugin); err != nil {
3636
return nil, httpresponse.ErrInternalError.Withf("%s for %q", err, name)
3737
} else {
3838
p.meta[name] = meta
@@ -83,14 +83,17 @@ func (p *parser) jsonParse(root ast.Node) error {
8383

8484
// tree should contain <dict plugin:<dict values> plugin:<dict values> ...>
8585
for _, plugins := range root.Children() {
86+
if plugins.Type() != ast.Ident {
87+
return httpresponse.ErrBadRequest.Withf("expected identifier, got %s", plugins.Type())
88+
}
8689
plugin := plugins.Value().(string)
87-
if plugin, exists := p.meta[plugin]; !exists {
90+
if plugin_, exists := p.meta[plugin]; !exists {
8891
return httpresponse.ErrNotFound.Withf("plugin not found: %q", plugin)
8992
} else if children := plugins.Children(); len(children) != 1 {
9093
return httpresponse.ErrBadRequest.Withf("expected one child, got %d", len(children))
9194
} else if dict := children[0]; dict.Type() != ast.Dict {
9295
return httpresponse.ErrBadRequest.Withf("expected object, got %s", dict.Type())
93-
} else if err := plugin.Validate(dict.Value()); err != nil {
96+
} else if err := plugin_.Validate(dict.Value()); err != nil {
9497
return err
9598
}
9699
}

0 commit comments

Comments
 (0)