Skip to content

✨ Marker support for Rust file extension .rs #4827

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

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

mabulgu
Copy link

@mabulgu mabulgu commented May 25, 2025

I have a new Operator SDK plugin for Rust*, and I use kubebuilder markers for scaffolding. This PR adds the .rs extension support to the marker.

Here is the plugin repo: https://github.com/SystemCraftsman/rust-operator-plugins

I would like to suggest this to be included in the Operator SDK org later on (gonna do that via the issue that I will open there).

Also I see the message When adding additional file extensions, update also the NewMarkerFor documentation and error, but no idea where I can update these. If anyone can show me the way, I can also update them to include Rust file ext.

(*) I recently presented the plugin in a KCD event: https://speakerdeck.com/mabulgu/building-kubernetes-operators-in-rust-a-new-operator-sdk-plugin

Copy link

linux-foundation-easycla bot commented May 25, 2025

CLA Signed


The committers listed above are authorized under a signed CLA.

@k8s-ci-robot k8s-ci-robot added the cncf-cla: no Indicates the PR's author has not signed the CNCF CLA. label May 25, 2025
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: mabulgu
Once this PR has been reviewed and has the lgtm label, please assign camilamacedo86 for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot
Copy link
Contributor

Welcome @mabulgu!

It looks like this is your first PR to kubernetes-sigs/kubebuilder 🎉. Please refer to our pull request process documentation to help your PR have a smooth ride to approval.

You will be prompted by a bot to use commands during the review process. Do not be afraid to follow the prompts! It is okay to experiment. Here is the bot commands documentation.

You can also check if kubernetes-sigs/kubebuilder has its own contribution guidelines.

You may want to refer to our testing guide if you run into trouble with your tests not passing.

If you are having difficulty getting your pull request seen, please follow the recommended escalation practices. Also, for tips and tricks in the contribution process you may want to read the Kubernetes contributor cheat sheet. We want to make sure your contribution gets all the attention it needs!

Thank you, and welcome to Kubernetes. 😃

@k8s-ci-robot k8s-ci-robot added needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. size/XS Denotes a PR that changes 0-9 lines, ignoring generated files. labels May 25, 2025
@k8s-ci-robot
Copy link
Contributor

Hi @mabulgu. Thanks for your PR.

I'm waiting for a kubernetes-sigs member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository.

@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. and removed cncf-cla: no Indicates the PR's author has not signed the CNCF CLA. labels May 25, 2025
Copy link
Member

@camilamacedo86 camilamacedo86 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @mabulgu 👋

It is VERY cool that you are creating an external plugin!!! 🎉
Thank you so much for building in the ecosystem and even presenting it at KCD — that's amazing!

We might even start tracking all external plugins and promoting them somewhere in the Kubebuilder docs. I’ll create a task for that — because your work deserves to be seen! 💡


🧭 About the PR to Add .rs Marker Support

However, in this case, Kubebuilder itself does not scaffold or use .rs files directly.

So for now, we won’t add .rs to the core marker support. This helps us keep the core focused only on what it uses internally.

But don’t worry! You can absolutely use Kubebuilder as a library and create your own custom markers to support .rs, or any other extension you want 🚀


📚 We should definitely create a doc for this:

“How to create my own markers for my own extensions not supported in Kubebuilder itself”

Here’s an example to help you (and others!) get started right away:


✅ Example: External Plugin With Custom .rs Marker Support

Using sigs.k8s.io/kubebuilder/v4/pkg/machinery

// plugin/marker.go
package plugin

import (
	"fmt"
	"path/filepath"
	"strings"

	"sigs.k8s.io/kubebuilder/v4/pkg/machinery"
)

const myPrefix = "+myplugin:scaffold:"

var rustCommentsByExt = map[string]string{
	".rs": "//",
}

type Marker struct {
	machinery.Marker
}

func NewRustMarker(path string, value string) Marker {
	ext := filepath.Ext(path)
	if comment, ok := rustCommentsByExt[ext]; ok {
		return Marker{
			machinery.Marker{
				prefix:  markerPrefix(myPrefix),
				comment: comment,
				value:   value,
			},
		}
	}
	panic(fmt.Errorf("unsupported file extension: %s", ext))
}

func markerPrefix(prefix string) string {
	trimmed := strings.TrimSpace(prefix)
	var builder strings.Builder
	if !strings.HasPrefix(trimmed, "+") {
		builder.WriteString("+")
	}
	builder.WriteString(trimmed)
	if !strings.HasSuffix(trimmed, ":") {
		builder.WriteString(":")
	}
	return builder.String()
}
// plugin/scaffold.go
package plugin

import (
	"strings"

	"sigs.k8s.io/kubebuilder/v4/pkg/machinery"
)

type RustMainFile struct {
	machinery.TemplateMixin
}

var _ machinery.Template = &RustMainFile{}

func (f *RustMainFile) SetTemplateDefaults() error {
	if f.Path == "" {
		f.Path = "main.rs"
	}

	f.TemplateBody = `{{ .ScaffoldMarker }}
fn main() {
    println!("Hello, operator!");
}
`

	m := NewRustMarker(f.Path, "mainFunc")
	f.IfExistsAction = machinery.OverwriteFile
	f.TemplateBody = strings.ReplaceAll(f.TemplateBody, "{{ .ScaffoldMarker }}", m.String())

	return nil
}
// main.go
package main

import (
	"sigs.k8s.io/kubebuilder/v4/pkg/plugin"
	"sigs.k8s.io/kubebuilder/v4/pkg/plugin/external"

	"myplugin/plugin"
)

func main() {
	external.Run(&external.Plugin{
		Name:    "my-rust.plugin",
		Version: plugin.Version{Number: 1},
		SupportedProjectVersions: []string{"3"},
		DevPhase: plugin.Alpha,

		GetScaffolder: func(c plugin.Context, args []string) (plugin.Scaffolder, error) {
			return &external.Scaffolder{
				Templates: []machinery.Template{
					&plugin.RustMainFile{},
				},
			}, nil
		},
	})
}

Again, HUGE thanks for contributing — we love seeing people build new ideas like this.
Keep going, and let’s grow the ecosystem together 🙌 — and yes, we will absolutely help promote these external plugins! 💖

@mabulgu
Copy link
Author

mabulgu commented May 25, 2025

@camilamacedo86 thanks for your quick response, and I appreciate your comments! I was actually using sth similar to what you suggested as a custom marker. Let me reevrt to that one then and see if that aligns with your suggestion above. Then I will close this PR once everything works as expected.

@@ -28,6 +28,7 @@ var commentsByExt = map[string]string{
".go": "//",
".yaml": "#",
".yml": "#",
".rs": "//",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We cannot add a file that we do not support have officially
Could the extension not be added in your code using the lib?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah no problem, I got that:) What I meant: I will try what you suggest above, and actually the way I had implemented it was like what you suggested above. Let me revert to what I had before and compare with your suggestion and see if that works. I dont remember why I avoided that approach, maybe just not to duplicate things (thinking I can have the rs extension definition in kubebuilder)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@camilamacedo86 ok I've tried and remembered the reason as I tried to use the same approach. Here it is:

Screenshot 2025-05-25 at 22 04 02

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So in other words, if we can make the marker struct use public fields instead of private ones, any other plugins can use their own custom markers.

I can create a PR for this if this sounds good to you?

Copy link
Author

@mabulgu mabulgu May 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making the fields public worked for me: mabulgu@4a61855

I can create a PR for this (not via the above branch of course, with a new one) because without this change I dont think anyone can use a custom marker.

Here is the implementation on the plugin: https://github.com/SystemCraftsman/rust-operator-plugins/blob/main/pkg/plugins/rust/marker.go

This might help us create the documentation for the custom marker. I can help with that as well.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, sure. Thank you a lot !!!
Yes, we need to allow people does that and create their own markers for their own extensions.
Please, feel free to raise the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. size/XS Denotes a PR that changes 0-9 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants