Skip to content

Commit 1d41656

Browse files
committed
📝 Address PR feedback: Update custom markers documentation
- Remove Key Considerations section per reviewer feedback - Update external plugin example to match current API pattern - Fix external plugin integration code to use JSON/STDIN communication - Simplify template example to be more realistic for external plugins - Merge latest changes from master branch Addresses feedback from PR review comments
1 parent f6f9a01 commit 1d41656

File tree

1 file changed

+91
-43
lines changed

1 file changed

+91
-43
lines changed

docs/book/src/plugins/extending/custom-markers.md

Lines changed: 91 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -77,34 +77,23 @@ func formatPrefix(prefix string) string {
7777
}
7878
```
7979

80-
### Use in Template Files
80+
### Use in Template Generation
8181

8282
```go
8383
package templates
8484

8585
import (
8686
"fmt"
87-
"path/filepath"
88-
"sigs.k8s.io/kubebuilder/v4/pkg/machinery"
8987
"github.com/yourorg/yourplugin/pkg/markers"
9088
)
9189

92-
type RustMainFile struct {
93-
machinery.TemplateMixin
94-
machinery.ProjectNameMixin
95-
}
96-
97-
func (f *RustMainFile) SetTemplateDefaults() error {
98-
if f.Path == "" {
99-
f.Path = filepath.Join("src", "main.rs")
100-
}
101-
102-
marker, err := markers.NewRustMarker(f.Path, "imports")
90+
func GenerateRustFile(projectName string) (string, error) {
91+
marker, err := markers.NewRustMarker("src/main.rs", "imports")
10392
if err != nil {
104-
return err
93+
return "", err
10594
}
10695

107-
f.TemplateBody = fmt.Sprintf(`// Generated by Rust Plugin
96+
content := fmt.Sprintf(`// Generated by Rust Plugin
10897
%s
10998
11099
use std::error::Error;
@@ -113,9 +102,19 @@ fn main() -> Result<(), Box<dyn Error>> {
113102
println!("Hello from %s!");
114103
Ok(())
115104
}
116-
`, marker.String(), f.ProjectName)
105+
`, marker.String(), projectName)
117106

118-
return nil
107+
return content, nil
108+
}
109+
110+
func GenerateCargoToml(projectName string) string {
111+
return fmt.Sprintf(`[package]
112+
name = "%s"
113+
version = "0.1.0"
114+
edition = "2021"
115+
116+
[dependencies]
117+
`, projectName)
119118
}
120119
```
121120

@@ -125,27 +124,86 @@ fn main() -> Result<(), Box<dyn Error>> {
125124
package main
126125

127126
import (
128-
"sigs.k8s.io/kubebuilder/v4/pkg/plugin"
127+
"bufio"
128+
"encoding/json"
129+
"fmt"
130+
"io"
131+
"os"
132+
"path/filepath"
133+
129134
"sigs.k8s.io/kubebuilder/v4/pkg/plugin/external"
130-
"github.com/yourorg/yourplugin/pkg/templates"
135+
"github.com/yourorg/yourplugin/pkg/markers"
131136
)
132137

133138
func main() {
134-
p := &external.Plugin{
135-
Name: "rust.kubebuilder.io",
136-
Version: plugin.Version{Number: 1, Stage: plugin.Alpha},
137-
138-
Init: func(req external.PluginRequest) external.PluginResponse {
139-
mainFile := &templates.RustMainFile{}
140-
141-
return external.PluginResponse{
142-
Universe: req.Universe,
143-
Files: []machinery.File{mainFile},
144-
}
145-
},
139+
// External plugins communicate via JSON over STDIN/STDOUT
140+
reader := bufio.NewReader(os.Stdin)
141+
input, err := io.ReadAll(reader)
142+
if err != nil {
143+
returnError(fmt.Errorf("error reading STDIN: %w", err))
144+
return
146145
}
147146

148-
external.Run(p)
147+
pluginRequest := &external.PluginRequest{}
148+
err = json.Unmarshal(input, pluginRequest)
149+
if err != nil {
150+
returnError(fmt.Errorf("error unmarshaling request: %w", err))
151+
return
152+
}
153+
154+
var response external.PluginResponse
155+
156+
switch pluginRequest.Command {
157+
case "init":
158+
response = handleInit(pluginRequest)
159+
case "flags":
160+
response = handleFlags(pluginRequest)
161+
case "metadata":
162+
response = handleMetadata(pluginRequest)
163+
default:
164+
response = external.PluginResponse{
165+
Command: pluginRequest.Command,
166+
Error: true,
167+
ErrorMsgs: []string{fmt.Sprintf("unknown command: %s", pluginRequest.Command)},
168+
}
169+
}
170+
171+
output, _ := json.Marshal(response)
172+
fmt.Printf("%s", output)
173+
}
174+
175+
func handleInit(req *external.PluginRequest) external.PluginResponse {
176+
// Create Rust file with custom markers
177+
marker, _ := markers.NewRustMarker("src/main.rs", "imports")
178+
179+
fileContent := fmt.Sprintf(`// Generated by Rust Plugin
180+
%s
181+
182+
use std::error::Error;
183+
184+
fn main() -> Result<(), Box<dyn Error>> {
185+
println!("Hello from Rust!");
186+
Ok(())
187+
}
188+
`, marker.String())
189+
190+
// External plugins use "universe" to represent file changes
191+
universe := make(map[string]string)
192+
universe["src/main.rs"] = fileContent
193+
194+
return external.PluginResponse{
195+
Command: "init",
196+
Universe: universe,
197+
}
198+
}
199+
200+
func returnError(err error) {
201+
response := external.PluginResponse{
202+
Error: true,
203+
ErrorMsgs: []string{err.Error()},
204+
}
205+
output, _ := json.Marshal(response)
206+
fmt.Printf("%s", output)
149207
}
150208
```
151209

@@ -157,14 +215,4 @@ To support other file extensions, modify the marker implementation by changing:
157215
- The file extension check (e.g., `.java`, `.py`, `.tpl`)
158216
- The marker prefix (e.g., `+java:scaffold:`, `+python:scaffold:`)
159217

160-
## Key Considerations
161-
162-
1. **Unique Prefixes**: Choose a unique prefix for your plugin to avoid conflicts (e.g., `+rust:scaffold:`, `+java:scaffold:`)
163-
164-
2. **Comment Syntax**: Different languages have different comment syntax. Ensure you map the correct comment style for each file extension
165-
166-
3. **Error Handling**: Validate file extensions and return clear error messages for unsupported files
167-
168-
4. **Testing**: Test your marker implementation with various scenarios to ensure reliability
169-
170218
For more information on creating external plugins, see [External Plugins](external-plugins.md).

0 commit comments

Comments
 (0)