-
Notifications
You must be signed in to change notification settings - Fork 260
detect template type from input, but respect explicit specification #1844
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
base: master
Are you sure you want to change the base?
detect template type from input, but respect explicit specification #1844
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #1844 +/- ##
==========================================
+ Coverage 57.52% 57.57% +0.04%
==========================================
Files 136 138 +2
Lines 12934 13038 +104
==========================================
+ Hits 7440 7506 +66
- Misses 4339 4376 +37
- Partials 1155 1156 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
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.
Pull request overview
This PR refactors the template rendering system to support automatic template type detection based on schema fields, while still allowing explicit type specification. The changes consolidate the previously separate basic and semver subcommands into a unified render-template command that can auto-detect the template type from the input file's schema field.
Key Changes:
- Introduced a common
Templateinterface and factory pattern for all template types - Implemented schema-based auto-detection using a registry system
- Unified the command structure from separate subcommands to a single command with optional type specification
Reviewed changes
Copilot reviewed 10 out of 10 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
cmd/opm/alpha/template/cmd.go |
Replaced separate subcommands with unified render-template command that accepts optional TYPE and FILE arguments |
cmd/opm/alpha/template/render.go |
New file implementing unified rendering logic with auto-detection and explicit type specification support |
cmd/opm/alpha/template/basic.go |
Removed - functionality moved to unified render.go |
cmd/opm/alpha/template/semver.go |
Removed - functionality moved to unified render.go |
alpha/template/template.go |
New file defining Template interface, TemplateFactory interface, and Registry for schema-based template creation |
alpha/template/schema.go |
New file implementing schema detection from YAML/JSON input |
alpha/template/basic/basic.go |
Refactored to implement new Template interface with factory pattern; renamed data struct to BasicTemplateData |
alpha/template/semver/semver.go |
Refactored to implement new Template interface with factory pattern; moved type definitions from types.go and renamed to SemverTemplateData |
alpha/template/semver/types.go |
Removed - content migrated into semver.go |
alpha/template/semver/semver_test.go |
Updated test assertions to use SemverTemplateData and changed to ElementsMatch for order-independent comparison |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.
32017ae to
23b2348
Compare
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.
Pull request overview
Copilot reviewed 10 out of 10 changed files in this pull request and generated 8 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.
23b2348 to
938b01d
Compare
Signed-off-by: grokspawn <jordan@nimblewidget.com>
7e6e569 to
0ff64da
Compare
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.
Pull request overview
Copilot reviewed 12 out of 12 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review for a chance to win a $100 gift card. Take the survey.
745a3f7 to
cd4bc48
Compare
| } | ||
|
|
||
| return bt, nil | ||
| // RenderBundle implements the template.Template interface |
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.
these docs lines are not very much helpful, can you expand for clarity?
alpha/template/template.go
Outdated
| "github.com/operator-framework/operator-registry/alpha/declcfg" | ||
| ) | ||
|
|
||
| // BundleRenderer defines the function signature for rendering bundle images |
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.
what is the semantic of string arg, what does it contain?
can you expand on the doc as well?
| // BundleRenderer defines the function signature for rendering bundle images | ||
| type BundleRenderer func(context.Context, string) (*declcfg.DeclarativeConfig, error) | ||
|
|
||
| // Template defines the common interface for all template types |
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.
please expand on what the template is?
alpha/template/template.go
Outdated
|
|
||
| // TemplateRegistry maintains a mapping of schema identifiers to template factories | ||
| type TemplateRegistry struct { | ||
| factories map[string]TemplateFactory |
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.
how about to use set.Set type here?
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.
We're mapping between the schema identifiers for templates supported by the factory, and the generator function stored in the factory, so a set would only make sense here if our type were self-expressing or we validated fitness characteristics before invoking it, whereas this approach allows us to invoke non-error returns.
| // and returns a reader that can be used to render the template. The returned reader includes | ||
| // both the data consumed during schema detection and the remaining unconsumed data. |
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.
could returned reader be hidden inside the returned Template instance? can this reader be used independently?
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.
It could be hidden in the template type, but it's arbitrary. The template is only interested in the reader as an input source, but it isn't inherently a template concern. It's just a general I/O one.
Signed-off-by: grokspawn <jordan@nimblewidget.com>
cd4bc48 to
9e351fc
Compare
|
Thanks for the really detailed review @pedjak! I've included changes which hopefully resolve your concerns and address ambiguity in the PR. Please give it another once over when you have a chance. |
|
|
||
| // GetTemplateRegistry returns the global template registry | ||
| func GetTemplateRegistry() *TemplateRegistry { | ||
| func GetTemplateRegistry() *templateRegistry { |
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.
can we return here an interface instead?
|
|
||
| type Template struct { | ||
| RenderBundle func(context.Context, string) (*declcfg.DeclarativeConfig, error) | ||
| func init() { |
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.
this init funciton is called only when we import alpha/template/basic package. Hence, only then we are going to register this Factory.
IMHO, we should register it at the other end - within alpha/template/registry.go - in that way all available factories will be registered always.
| type Factory struct{} | ||
|
|
||
| // CreateTemplate implements the template.TemplateFactory interface | ||
| func (f *Factory) CreateTemplate(renderBundle template.BundleRenderer) template.Template { |
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.
given that we call New() from Factory, should we actually have New() function public?
| return schema | ||
| } | ||
|
|
||
| type BasicTemplateData struct { |
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.
does it need to be public?
|
|
||
| func (t Template) Render(ctx context.Context) (*declcfg.DeclarativeConfig, error) { | ||
| // IO structs -- BEGIN | ||
| type semverTemplateBundleEntry struct { |
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.
given that we are in semver package, I would suggest to drop semver prefix from the types declared here, the redundancy does not bring much.
| Bundles []semverTemplateBundleEntry `json:"bundles,omitempty"` | ||
| } | ||
|
|
||
| type SemverTemplateData struct { |
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.
does this need to be public? It is a bit strange that a caller get access to a type, that has member fields of a private type.
| type Factory struct{} | ||
|
|
||
| // CreateTemplate implements the template.TemplateFactory interface | ||
| func (f *Factory) CreateTemplate(renderBundle template.BundleRenderer) template.Template { |
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.
same question as for the basic factory.
| const schema string = "olm.semver" | ||
|
|
||
| func init() { | ||
| template.GetTemplateRegistry().Register(&Factory{}) |
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.
same question as for basic factory.
| return schema | ||
| } | ||
|
|
||
| const schema string = "olm.semver" |
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.
can you move it at the top of the file?
| type channelArchetype string | ||
|
|
||
| const ( | ||
| candidateChannelArchetype channelArchetype = "candidate" | ||
| fastChannelArchetype channelArchetype = "fast" | ||
| stableChannelArchetype channelArchetype = "stable" | ||
| ) | ||
|
|
||
| // mapping channel name --> stability, where higher values indicate greater stability | ||
| var channelPriorities = map[channelArchetype]int{candidateChannelArchetype: 0, fastChannelArchetype: 1, stableChannelArchetype: 2} |
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.
can you move it to the top of the file?
Description of the change:
Replaces #1814
Various type changes and refactoring necessary to make opm alpha render-template capable of detecting the template type from sniffing its schema, as well as name standardization across all template types and a new factory-based creation pattern.
This absolutely sacrifices stability of the API in favor of stability of the datatypes and callflows for future growth.
Motivation for the change:
Since we created a formal schema for the basic catalog template, it made much more sense for Template to be an interface for a creation/call pattern which was increasingly entrenched in users' tooling... so it was easy to put off. But since it was also largely a "move existing stuff around" activity (read: super simple operations with complex propagation and high potential for side effects), it seemed a great opportunity to see what Claude would do with it.
Reviewer Checklist
/docs