Repository navigation
First stab from claude #820
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,65 +1,21 @@ | ||
| package capability | ||
|
|
||
| import ( | ||
| "reflect" | ||
|
|
||
| "google.golang.org/protobuf/reflect/protoreflect" | ||
|
|
||
| "github.com/smartcontractkit/chainlink-common/pkg/capabilities" | ||
| "github.com/smartcontractkit/chainlink-common/pkg/logger" | ||
| "github.com/smartcontractkit/chainlink-common/pkg/services" | ||
| "github.com/smartcontractkit/chainlink-common/pkg/settings/limits" | ||
| "github.com/smartcontractkit/chainlink-common/pkg/types/core" | ||
| ) | ||
|
|
||
| type Capability interface { | ||
| services.Service | ||
| capabilities.ExecutableAndTriggerCapability | ||
|
|
||
| // Service is the proto service this capability's server was generated from. | ||
| Service() protoreflect.ServiceDescriptor | ||
| } | ||
|
|
||
| // Config marks the struct a constructor asks for as the capability's own configuration | ||
| // | ||
| // type Config struct { | ||
| // capability.Config | ||
| // FastestScheduleIntervalSeconds int `usage:"fastest cron schedule a workflow may register"` | ||
| // } | ||
| // | ||
| // The run binds the struct's fields as flags on the root command, namespaced by the binary's | ||
| // name - cron's are --cron.fastest-schedule-interval-seconds, CRE_CRON_FASTEST_SCHEDULE_INTERVAL_SECONDS, | ||
| // or the same key in the config file - and hands the constructor the decoded value. A constructor | ||
| // declares at most one. | ||
| type Config struct{} | ||
|
|
||
| // capabilityConfig is what a capability binary needs from the node it runs beside. | ||
| type capabilityConfig struct { | ||
| ProxyURL string `usage:"gRPC target of the node's capability registry proxy (e.g. localhost:9000), used to resolve capabilities this binary does not host. Unset resolves only the capabilities this binary hosts"` | ||
| CapabilityDonID uint32 `usage:"on-chain DON ID of the capability DON this process was spawned for"` | ||
|
|
||
| // Serves the Debug UI | ||
| HTTPDebug bool `usage:"serve the capability debug UI on the shared HTTP server, under /debug/capabilities"` | ||
| } | ||
|
|
||
| type Dependencies struct { | ||
| Logger logger.Logger | ||
| CapabilityRegistry core.CapabilitiesRegistry | ||
| LimitsFactory limits.Factory | ||
| } | ||
|
|
||
| func (d Dependencies) list() []any { | ||
| return []any{d.Logger, d.CapabilityRegistry, d.LimitsFactory} | ||
| } | ||
|
|
||
| func (d Dependencies) resolve(want reflect.Type) (reflect.Value, bool) { | ||
| for _, v := range d.list() { | ||
| if v == nil { | ||
| continue | ||
| } | ||
| if got := reflect.TypeOf(v); got.AssignableTo(want) { | ||
| return reflect.ValueOf(v), true | ||
| } | ||
| } | ||
| return reflect.Value{}, false | ||
| // ProxyURL is the gRPC target of the node's capability registry proxy (e.g. localhost:9000), | ||
| // used to resolve capabilities this binary does not host. Unset resolves only the capabilities | ||
| // this binary hosts. | ||
| ProxyURL string | ||
| // CapabilityDonID is the on-chain DON ID of the capability DON this process was spawned for. | ||
| CapabilityDonID uint32 | ||
| } |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| package capability | ||
|
|
||
| import ( | ||
| "maps" | ||
| "slices" | ||
|
|
||
| "github.com/spf13/cobra" | ||
|
|
||
| "github.com/smartcontractkit/chainlink-common/x/config/commentparsing" | ||
| "github.com/smartcontractkit/chainlink-common/x/config/markup/tomlmarkup" | ||
| ) | ||
|
|
||
| // docsCommand generates the DocComments every config bound on the binary needs for its flags' help | ||
| // text, so a capability's own config is documented by running its binary rather than by a | ||
| // generator of its own: | ||
| // | ||
| // //go:generate go run . docs | ||
| // | ||
| // It writes a doccomments_gen.go beside each config struct - registered with ProvideConfig, by this | ||
| // package or any dependency - declared in the module enclosing the working directory. A struct from another module - this package's sections, when a capability | ||
| // binary runs it - is read from the DocComments that module already compiled in, so this package | ||
| // generates its own too (see internal/docgen). | ||
| // | ||
| // The binder decodes before any command runs, docs included, so a config with a required field | ||
| // has to be satisfied to generate its docs. | ||
| // | ||
| // It documents what both commands register: each registers configs the other does not - | ||
| // capabilities differs between them, say. | ||
| func docsCommand() *cobra.Command { | ||
| return &cobra.Command{ | ||
| Use: "docs", | ||
| Short: "Generate the doc comments the config's help text is read from", | ||
| Args: cobra.NoArgs, | ||
| RunE: func(cmd *cobra.Command, _ []string) error { | ||
| var roots []any | ||
| for _, r := range []*registrations{runRegistrations, embedRegistrations} { | ||
| for _, namespace := range slices.Sorted(maps.Keys(r.configs)) { | ||
| roots = append(roots, r.configs[namespace].value) | ||
| } | ||
| } | ||
|
|
||
| return commentparsing.Run(commentparsing.RunArgs{ | ||
| Roots: roots, | ||
| Markup: tomlmarkup.New(), | ||
| // Per binary: a run removes files its Tool wrote and did not produce this time, so | ||
| // two binaries in one module sharing a name would delete each other's. | ||
| Tool: cmd.Root().Name() + " docs", | ||
| LocalPrefix: "github.com/smartcontractkit", | ||
| }) | ||
| }, | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| package capability | ||
|
|
||
| // embedConfig is the embed command's own config, registered on that command alone. | ||
| type embedConfig struct { | ||
| // Instances is how many instances of the capability this process hosts. | ||
| Instances int `validate:"min=1"` | ||
| } | ||
|
|
||
| // defaultEmbeddedDonID is the DON an embedded run reports. An embed run is one DON in one process, | ||
| // so there is only ever the one, and requiring it to be configured would mean typing the same | ||
| // number into every embedded run. | ||
| const defaultEmbeddedDonID = 1 | ||
|
|
||
| // embeddedCapabilityConfig is capabilityConfig as an embed run registers it, replacing run's under | ||
| // the same namespace. It keeps the DON ID and drops the proxy URL: there is no node behind an | ||
| // embedded run to dial, so only what this binary hosts resolves. | ||
| type embeddedCapabilityConfig struct { | ||
|
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ?? it's this hard-coded to the same value every time? Do we need it? |
||
| // CapabilityDonID is the on-chain DON ID reported for the capabilities this process hosts. | ||
| CapabilityDonID uint32 | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rename settings -> config -- settings refers to cre settings specifically