chore: import upstream snapshot with attribution
govulncheck / govulncheck (push) Has been cancelled
Lint / golangci-lint (push) Has been cancelled
Run Tests / Unit Tests (push) Has been cancelled
Run Tests / Etcd Integration Tests (push) Has been cancelled
Harness (E2E) / Harnesses (mock LLM) (push) Has been cancelled
Harness (E2E) / Provider harnesses (live LLM conformance) (push) Has been cancelled

This commit is contained in:
wehub-resource-sync
2026-07-13 12:40:33 +08:00
commit e071084ebe
982 changed files with 160368 additions and 0 deletions
+84
View File
@@ -0,0 +1,84 @@
package resource
import (
"fmt"
"os"
"os/signal"
"syscall"
"github.com/urfave/cli/v2"
"go-micro.dev/v6/broker"
)
// brokerCommand exposes the broker interface: publish, subscribe.
func brokerCommand() *cli.Command {
return &cli.Command{
Name: "broker",
Usage: "Publish and subscribe to broker topics",
Description: `Interact with the message broker.
micro broker publish <topic> <message> Publish a message to a topic
micro broker subscribe <topic> Stream messages from a topic`,
Subcommands: []*cli.Command{
{
Name: "publish",
Usage: "Publish a message to a topic",
ArgsUsage: "<topic> <message>",
Action: brokerPublish,
},
{
Name: "subscribe",
Usage: "Stream messages from a topic",
ArgsUsage: "<topic>",
Action: brokerSubscribe,
},
},
}
}
func brokerPublish(c *cli.Context) error {
topic := c.Args().Get(0)
msg := c.Args().Get(1)
if topic == "" || msg == "" {
return fail("usage: micro broker publish <topic> <message>")
}
b := broker.DefaultBroker
if err := b.Connect(); err != nil {
return fail("broker connect: %v", err)
}
if err := b.Publish(topic, &broker.Message{Body: []byte(msg)}); err != nil {
return fail("publish: %v", err)
}
fmt.Printf("Published to %q\n", topic)
return nil
}
func brokerSubscribe(c *cli.Context) error {
topic := c.Args().First()
if topic == "" {
return fail("usage: micro broker subscribe <topic>")
}
b := broker.DefaultBroker
if err := b.Connect(); err != nil {
return fail("broker connect: %v", err)
}
sub, err := b.Subscribe(topic, func(e broker.Event) error {
fmt.Printf("%s\n", string(e.Message().Body))
return nil
})
if err != nil {
return fail("subscribe: %v", err)
}
defer func() { _ = sub.Unsubscribe() }()
fmt.Printf("Subscribed to %q (Ctrl-C to stop)...\n", topic)
sig := make(chan os.Signal, 1)
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
<-sig
return nil
}
+79
View File
@@ -0,0 +1,79 @@
package resource
import (
"fmt"
"strings"
"github.com/urfave/cli/v2"
"go-micro.dev/v6/config"
"go-micro.dev/v6/config/source/env"
)
// configCommand exposes the config interface: get, dump.
//
// The CLI loads configuration from environment variables (the source
// that makes sense without a running service). Keys use dot notation,
// e.g. "database.host" reads from DATABASE_HOST.
func configCommand() *cli.Command {
return &cli.Command{
Name: "config",
Usage: "Read dynamic configuration (from environment)",
Description: `Read dynamic configuration loaded from environment variables.
Keys use dot notation: "database.host" maps to DATABASE_HOST.
micro config get <key> Read a config value
micro config dump Print the full config as JSON`,
Subcommands: []*cli.Command{
{
Name: "get",
Usage: "Read a config value",
ArgsUsage: "<key>",
Action: configGet,
},
{
Name: "dump",
Usage: "Print the full config",
Action: configDump,
},
},
}
}
func loadConfig() (config.Config, error) {
conf, err := config.NewConfig()
if err != nil {
return nil, err
}
if err := conf.Load(env.NewSource()); err != nil {
return nil, err
}
return conf, nil
}
func configGet(c *cli.Context) error {
key := c.Args().First()
if key == "" {
return fail("usage: micro config get <key>")
}
conf, err := loadConfig()
if err != nil {
return fail("load config: %v", err)
}
path := strings.Split(key, ".")
val, err := conf.Get(path...)
if err != nil {
return fail("get %q: %v", key, err)
}
fmt.Println(string(val.Bytes()))
return nil
}
func configDump(c *cli.Context) error {
conf, err := loadConfig()
if err != nil {
return fail("load config: %v", err)
}
fmt.Println(string(conf.Bytes()))
return nil
}
+92
View File
@@ -0,0 +1,92 @@
package resource
import (
"fmt"
"github.com/urfave/cli/v2"
"go-micro.dev/v6/registry"
)
// registryCommand exposes the registry interface: list, get, watch.
func registryCommand() *cli.Command {
return &cli.Command{
Name: "registry",
Usage: "Inspect the service registry",
Description: `Interact with the service registry.
micro registry list List all registered services
micro registry get <name> Show nodes and endpoints for a service
micro registry watch Stream registration events`,
Subcommands: []*cli.Command{
{
Name: "list",
Usage: "List all registered services",
Action: registryList,
},
{
Name: "get",
Usage: "Show details for a service",
ArgsUsage: "<name>",
Action: registryGet,
},
{
Name: "watch",
Usage: "Stream registration events",
Action: registryWatch,
},
},
}
}
func registryList(c *cli.Context) error {
services, err := registry.ListServices()
if err != nil {
return fail("list services: %v", err)
}
out := make([]map[string]any, 0, len(services))
for _, s := range services {
out = append(out, map[string]any{
"name": s.Name,
"version": s.Version,
})
}
return printJSON(out)
}
func registryGet(c *cli.Context) error {
name := c.Args().First()
if name == "" {
return fail("usage: micro registry get <name>")
}
services, err := registry.GetService(name)
if err != nil {
return fail("get service %q: %v", name, err)
}
if len(services) == 0 {
return fail("service %q not found", name)
}
return printJSON(services)
}
func registryWatch(c *cli.Context) error {
w, err := registry.Watch()
if err != nil {
return fail("watch registry: %v", err)
}
defer w.Stop()
fmt.Println("Watching registry for changes (Ctrl-C to stop)...")
for {
res, err := w.Next()
if err != nil {
return fail("watch: %v", err)
}
name := ""
version := ""
if res.Service != nil {
name = res.Service.Name
version = res.Service.Version
}
fmt.Printf("%-10s %s %s\n", res.Action, name, version)
}
}
+52
View File
@@ -0,0 +1,52 @@
// Package resource provides CLI commands that map directly onto
// go-micro's core interfaces — registry, broker, store, and config.
//
// Each interface gets its own top-level command with verbs that mirror
// the interface methods, so the framework's building blocks are
// inspectable and manipulable from the terminal:
//
// micro registry list
// micro broker publish <topic> <message>
// micro store read <key>
// micro config get <key>
//
// New resource commands are registered by appending to the commands
// slice in init — see registry.go, broker.go, store.go, config.go for
// the per-interface implementations.
package resource
import (
"encoding/json"
"fmt"
"os"
"github.com/urfave/cli/v2"
"go-micro.dev/v6/cmd"
)
// commandFunc returns a cli.Command for a single core interface. Add a
// new one here to expose another package on the CLI.
var commandFuncs = []func() *cli.Command{
registryCommand,
brokerCommand,
storeCommand,
configCommand,
}
func init() {
for _, fn := range commandFuncs {
cmd.Register(fn())
}
}
// printJSON writes v as indented JSON to stdout.
func printJSON(v any) error {
enc := json.NewEncoder(os.Stdout)
enc.SetIndent("", " ")
return enc.Encode(v)
}
// fail returns a cli error with a consistent prefix.
func fail(format string, args ...any) error {
return cli.Exit(fmt.Sprintf(format, args...), 1)
}
+29
View File
@@ -0,0 +1,29 @@
package resource
import "testing"
func TestCommandsRegistered(t *testing.T) {
// Each command func must return a command with a name and at least
// one subcommand, so the resource surface stays consistent.
for _, fn := range commandFuncs {
c := fn()
if c.Name == "" {
t.Error("command with empty name")
}
if len(c.Subcommands) == 0 {
t.Errorf("command %q has no subcommands", c.Name)
}
}
}
func TestExpectedCommands(t *testing.T) {
names := map[string]bool{}
for _, fn := range commandFuncs {
names[fn().Name] = true
}
for _, want := range []string{"registry", "broker", "store", "config"} {
if !names[want] {
t.Errorf("missing %q command", want)
}
}
}
+106
View File
@@ -0,0 +1,106 @@
package resource
import (
"fmt"
"github.com/urfave/cli/v2"
"go-micro.dev/v6/store"
)
// storeCommand exposes the store interface: read, write, delete, list.
func storeCommand() *cli.Command {
return &cli.Command{
Name: "store",
Usage: "Read and write records in the store",
Description: `Interact with the data store.
micro store list [prefix] List keys (optionally by prefix)
micro store read <key> Read a record
micro store write <key> <value> Write a record
micro store delete <key> Delete a record`,
Subcommands: []*cli.Command{
{
Name: "list",
Usage: "List keys",
ArgsUsage: "[prefix]",
Action: storeList,
},
{
Name: "read",
Usage: "Read a record",
ArgsUsage: "<key>",
Action: storeRead,
},
{
Name: "write",
Usage: "Write a record",
ArgsUsage: "<key> <value>",
Action: storeWrite,
},
{
Name: "delete",
Usage: "Delete a record",
ArgsUsage: "<key>",
Action: storeDelete,
},
},
}
}
func storeList(c *cli.Context) error {
var opts []store.ListOption
if prefix := c.Args().First(); prefix != "" {
opts = append(opts, store.ListPrefix(prefix))
}
keys, err := store.DefaultStore.List(opts...)
if err != nil {
return fail("list: %v", err)
}
return printJSON(keys)
}
func storeRead(c *cli.Context) error {
key := c.Args().First()
if key == "" {
return fail("usage: micro store read <key>")
}
records, err := store.DefaultStore.Read(key)
if err != nil {
return fail("read %q: %v", key, err)
}
if len(records) == 0 {
return fail("key %q not found", key)
}
// Print the raw value for a single record, JSON for multiple.
if len(records) == 1 {
fmt.Println(string(records[0].Value))
return nil
}
return printJSON(records)
}
func storeWrite(c *cli.Context) error {
key := c.Args().Get(0)
value := c.Args().Get(1)
if key == "" {
return fail("usage: micro store write <key> <value>")
}
rec := &store.Record{Key: key, Value: []byte(value)}
if err := store.DefaultStore.Write(rec); err != nil {
return fail("write %q: %v", key, err)
}
fmt.Printf("Wrote %q\n", key)
return nil
}
func storeDelete(c *cli.Context) error {
key := c.Args().First()
if key == "" {
return fail("usage: micro store delete <key>")
}
if err := store.DefaultStore.Delete(key); err != nil {
return fail("delete %q: %v", key, err)
}
fmt.Printf("Deleted %q\n", key)
return nil
}