package main import ( "io" "net/url" "os" "sort" "time" "github.com/alecthomas/kong" "github.com/apex/log" "gitea.unbound.se/unboundsoftware/schemas/ctl" ) type Context struct { ApiKey string SchemaRef string SchemasURL url.URL logger log.Interface } type PublishCmd struct { Service string `name:"service" env:"SERVICE" help:"The service to publish SDL for" required:""` Url *url.URL `name:"url" env:"URL" help:"The URL of the service" optional:""` WSUrl *url.URL `name:"ws-url" env:"WS_URL" help:"The Websocket URL of the service" optional:""` SDL *os.File `name:"sdl" env:"SDL" help:"The file containing the GraphQL SDL" required:""` } func (c *PublishCmd) Run(ctx Context) error { buff, err := io.ReadAll(c.SDL) if err != nil { return err } subGraph, err := ctl.Publish(ctx.ApiKey, ctx.SchemaRef, c.Service, string(buff), c.Url, c.WSUrl, ctx.SchemasURL) if err != nil { return err } ctx.logger.Infof("published %s@%s %s", subGraph.Service, subGraph.ChangedAt.Format(time.RFC3339), subGraph.ChangedBy) return nil } type ListCmd struct { Service string `name:"service" env:"SERVICE" help:"The service to publish SDL for" optional:""` } func (c *ListCmd) Run(ctx Context) error { subGraphs, err := ctl.List(ctx.ApiKey, ctx.SchemaRef, c.Service, ctx.SchemasURL) if err != nil { return err } sort.SliceStable(subGraphs, func(i, j int) bool { return subGraphs[i].Service < subGraphs[j].Service }) for _, subGraph := range subGraphs { ctx.logger.Infof("%s URL: %s WS-URL: %s Changed: %s %s", subGraph.Service, emptyIfNil(subGraph.URL), emptyIfNil(subGraph.WSUrl), subGraph.ChangedAt.Format(time.RFC3339), subGraph.ChangedBy) } return nil } type CLI struct { ApiKey string `name:"api-key" env:"API_KEY" help:"The API-key to use when communicating with the server" required:""` SchemaRef string `name:"schema-ref" env:"SCHEMA_REF" help:"The schema reference to work with" required:""` OverrideSchemasUrl *url.URL `name:"override-schemas-url" env:"OVERRIDE_SCHEMAS_URL" help:"Use a specific URL when communicating with the Schemas-API" optional:""` Publish PublishCmd `cmd:""` List ListCmd `cmd:""` LogLevel string `name:"log-level" env:"LOG_LEVEL" help:"The level of logging to use (debug, info, warn, error, fatal)" default:"info"` } func main() { cli := CLI{} ctx := kong.Parse(&cli) log.SetLevelFromString(cli.LogLevel) logger := log.WithField("service", "schemactl") err := ctx.Run(Context{ApiKey: cli.ApiKey, SchemaRef: cli.SchemaRef, SchemasURL: schemasUrl(cli.OverrideSchemasUrl), logger: logger}) ctx.FatalIfErrorf(err) } func emptyIfNil(s *string) string { if s == nil { return "" } return *s } func schemasUrl(u *url.URL) url.URL { if u == nil { u, err := url.Parse("https://schemas.unbound.se/query") if err != nil { return url.URL{} } return *u } return *u }