Skip to content

Commit 87b0ef5

Browse files
authored
Configurable package namespaces/prefixes (#247)
Fixes: #246 Implemented according to the proposal I posted in #246. Tested manually with the CertManager CRDs, with and without the new CLI option, for `nodejs`, `python`, `dotnet` and `java`. As it needs to be, without the namespace/prefix option, I could verify the default value was still used. With the new namespace/prefix option, the value was integrated correctly in the generated files.
1 parent beb9734 commit 87b0ef5

File tree

12 files changed

+104
-52
lines changed

12 files changed

+104
-52
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# CHANGELOG
22

3+
## 1.6.0 (2025-10-17)
4+
5+
- Configurable package namespaces/prefixes. (https://github.com/pulumi/crd2pulumi/pull/247)
6+
37
## 1.5.4 (2024-11-13)
48

59
- NodeJS now uses correct input/output types for object metadata. (https://github.com/pulumi/crd2pulumi/issues/158)

README.md

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -59,23 +59,28 @@ Available Commands:
5959
version Print the version number of crd2pulumi
6060

6161
Flags:
62-
-d, --dotnet generate .NET
63-
--dotnetName string name of .NET package (default "crds")
64-
--dotnetPath string optional .NET output dir
65-
-f, --force overwrite existing files
66-
-g, --go generate Go
67-
--goName string name of Go package (default "crds")
68-
--goPath string optional Go output dir
69-
-h, --help help for crd2pulumi
70-
-j, --java generate Java
71-
--javaName string name of Java package (default "crds")
72-
--javaPath string optional Java output dir
73-
-n, --nodejs generate NodeJS
74-
--nodejsName string name of NodeJS package (default "crds")
75-
--nodejsPath string optional NodeJS output dir
76-
-p, --python generate Python
77-
--pythonName string name of Python package (default "crds")
78-
--pythonPath string optional Python output dir
62+
-d, --dotnet generate .NET
63+
--dotnetName string name of generated .NET package (default "crds")
64+
--dotnetNamespace string namespace of generated .NET package
65+
--dotnetPath string optional .NET output dir
66+
-f, --force overwrite existing files
67+
-g, --go generate Go
68+
--goName string name of generated Go package (default "crds")
69+
--goPath string optional Go output dir
70+
-h, --help help for crd2pulumi
71+
-j, --java generate Java
72+
--javaBasePackage string base package of generated Java package
73+
--javaName string name of generated Java package (default "crds")
74+
--javaPath string optional Java output dir
75+
-n, --nodejs generate NodeJS
76+
--nodejsName string name of generated NodeJS package (default "crds")
77+
--nodejsNamespace string namespace of generated NodeJS package
78+
--nodejsPath string optional NodeJS output dir
79+
-p, --python generate Python
80+
--pythonName string name of generated Python package (default "crds")
81+
--pythonPackagePrefix string prefix of generated Python package
82+
--pythonPath string optional Python output dir
83+
7984

8085
Use "crd2pulumi [command] --help" for more information about a command.
8186
```

cmd/root.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,11 @@ func New() *cobra.Command {
123123
f.StringVarP(&pythonSettings.PackageName, "pythonName", "", codegen.DefaultName, "name of generated Python package")
124124
f.StringVarP(&javaSettings.PackageName, "javaName", "", codegen.DefaultName, "name of generated Java package")
125125

126+
f.StringVarP(&dotNetSettings.PackageNamespace, "dotnetNamespace", "", "", "namespace of generated .NET package")
127+
f.StringVarP(&nodejsSettings.PackageNamespace, "nodejsNamespace", "", "", "namespace of generated NodeJS package")
128+
f.StringVarP(&pythonSettings.PackageNamespace, "pythonPackagePrefix", "", "", "prefix of generated Python package")
129+
f.StringVarP(&javaSettings.PackageNamespace, "javaBasePackage", "", "", "base package of generated Java package")
130+
126131
f.StringVarP(&dotNetSettings.OutputDir, "dotnetPath", "", "", "optional .NET output dir")
127132
f.StringVarP(&goSettings.OutputDir, "goPath", "", "", "optional Go output dir")
128133
f.StringVarP(&nodejsSettings.OutputDir, "nodejsPath", "", "", "optional NodeJS output dir")

mise.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[tools]
2+
3+
# Runtimes
4+
go = "1.24.3"
5+
node = '20.19.5'
6+
python = '3.11.8'
7+
dotnet = '8.0.414'
8+
# Corretto version used as Java SE/OpenJDK version no longer offered
9+
java = 'corretto-11'

pkg/codegen/codegen.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212

1313
// GenerateFunc is the function that is called by the generator to generate the code.
1414
// It returns a mapping of filename to the contents of said file and any error that may have occurred.
15-
type GenerateFunc func(pg *PackageGenerator, name string) (mapFileNameToData map[string]*bytes.Buffer, err error)
15+
type GenerateFunc func(pg *PackageGenerator, cs *CodegenSettings) (mapFileNameToData map[string]*bytes.Buffer, err error)
1616

1717
var codeGenFuncs = map[string]GenerateFunc{
1818
Go: GenerateGo,
@@ -59,7 +59,7 @@ func Generate(cs *CodegenSettings, yamls []io.ReadCloser) error {
5959
}
6060

6161
// Do actual codegen
62-
output, err := generate(pg, cs.PackageName)
62+
output, err := generate(pg, cs)
6363
if err != nil {
6464
return fmt.Errorf("failed to generate %q package %q: %w", cs.Language, cs.PackageName, err)
6565
}

pkg/codegen/dotnet.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ var unneededDotNetFiles = []string{
3232
"Provider.cs",
3333
}
3434

35-
func GenerateDotNet(pg *PackageGenerator, name string) (map[string]*bytes.Buffer, error) {
35+
func GenerateDotNet(pg *PackageGenerator, cs *CodegenSettings) (map[string]*bytes.Buffer, error) {
3636
pkg := pg.SchemaPackageWithObjectMetaType()
3737

3838
// Set up C# namespaces
@@ -56,7 +56,8 @@ func GenerateDotNet(pg *PackageGenerator, name string) (map[string]*bytes.Buffer
5656
// `Pulumi.Kubernetes.Types.Outputs.Meta.V1.ObjectMeta`. This path would
5757
// only get generated properly if `compatibility` was `kubernetes20`.
5858
oldName := pkg.Name
59-
pkg.Name = name
59+
pkg.Name = cs.PackageName
60+
pkg.Namespace = cs.PackageNamespace
6061
var err error
6162

6263
files, err := dotnet.GeneratePackage(PulumiToolName, pkg, nil, nil)
@@ -67,9 +68,13 @@ func GenerateDotNet(pg *PackageGenerator, name string) (map[string]*bytes.Buffer
6768
pkg.Name = oldName
6869
delete(pkg.Language, "csharp")
6970

70-
namespaceName := dotnet.Title(name)
71-
files["KubernetesResource.cs"] = []byte(kubernetesResource(namespaceName))
72-
files["Utilities.cs"] = []byte(dotNetUtilities(namespaceName))
71+
packageName := dotnet.Title(cs.PackageName)
72+
namespace := cs.PackageNamespace
73+
if namespace == "" {
74+
namespace = "Pulumi"
75+
}
76+
files["KubernetesResource.cs"] = []byte(kubernetesResource(namespace, packageName))
77+
files["Utilities.cs"] = []byte(dotNetUtilities(namespace, packageName))
7378

7479
// Delete unneeded files
7580
for _, unneededFile := range unneededDotNetFiles {
@@ -84,9 +89,9 @@ func GenerateDotNet(pg *PackageGenerator, name string) (map[string]*bytes.Buffer
8489
return buffers, nil
8590
}
8691

87-
func kubernetesResource(name string) string {
92+
func kubernetesResource(namespace string, name string) string {
8893
return `// Copyright 2016-2022, Pulumi Corporation
89-
namespace Pulumi.` + name + `{
94+
namespace ` + namespace + `.` + name + `{
9095
/// <summary>
9196
/// A base class for all Kubernetes resources.
9297
/// </summary>
@@ -116,15 +121,15 @@ namespace Pulumi.` + name + `{
116121
// tried running `pulumi up` with the normal `Utilities.cs` file.
117122
// As a temporary fix, this modified `Utilities.cs` file just removes the
118123
// `static Utilities()` method.
119-
func dotNetUtilities(name string) string {
124+
func dotNetUtilities(namespace string, name string) string {
120125
return `// *** WARNING: this file was generated by crd2pulumi. ***
121126
// *** Do not edit by hand unless you're certain you know what you are doing! ***
122127
123128
using System;
124129
using System.Reflection;
125130
using Pulumi.Kubernetes;
126131
127-
namespace Pulumi.` + name + `
132+
namespace ` + namespace + `.` + name + `
128133
{
129134
static class Utilities
130135
{

pkg/codegen/golang.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ var UnneededGoFiles = codegen.NewStringSet(
3636
"utilities/pulumiVersion.go",
3737
)
3838

39-
func GenerateGo(pg *PackageGenerator, name string) (buffers map[string]*bytes.Buffer, err error) {
39+
func GenerateGo(pg *PackageGenerator, cs *CodegenSettings) (buffers map[string]*bytes.Buffer, err error) {
4040
defer func() {
4141
if r := recover(); r != nil {
4242
err = fmt.Errorf("%v", r)
@@ -46,7 +46,7 @@ func GenerateGo(pg *PackageGenerator, name string) (buffers map[string]*bytes.Bu
4646
pkg := pg.SchemaPackageWithObjectMetaType()
4747
langName := "go"
4848
oldName := pkg.Name
49-
pkg.Name = name
49+
pkg.Name = cs.PackageName
5050
moduleToPackage, err := pg.ModuleToPackage()
5151
if err != nil {
5252
return nil, fmt.Errorf("%w", err)

pkg/codegen/java.go

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,13 @@ import (
1818
"bytes"
1919
"fmt"
2020
"regexp"
21+
"strings"
2122

2223
"github.com/pulumi/crd2pulumi/internal/versions"
2324
javaGen "github.com/pulumi/pulumi-java/pkg/codegen/java"
2425
)
2526

26-
func GenerateJava(pg *PackageGenerator, name string) (map[string]*bytes.Buffer, error) {
27+
func GenerateJava(pg *PackageGenerator, cs *CodegenSettings) (map[string]*bytes.Buffer, error) {
2728
pkg := pg.SchemaPackageWithObjectMetaType()
2829

2930
// These fields are required for the Java code generation
@@ -47,7 +48,19 @@ func GenerateJava(pg *PackageGenerator, name string) (map[string]*bytes.Buffer,
4748

4849
langName := "java"
4950
oldName := pkg.Name
50-
pkg.Name = name
51+
pkg.Name = cs.PackageName
52+
pkg.Namespace = cs.PackageNamespace
53+
54+
// Override Java base package to avoid pulumi-java defaulting logic adding an extra "com." prefix
55+
if pkg.Language == nil {
56+
pkg.Language = map[string]interface{}{}
57+
}
58+
pkg.Language[langName] = javaGen.PackageInfo{BasePackage: cs.PackageNamespace}
59+
60+
namespacePath := "com/pulumi"
61+
if cs.PackageNamespace != "" {
62+
namespacePath = strings.ReplaceAll(cs.PackageNamespace, ".", "/")
63+
}
5164

5265
files, err := javaGen.GeneratePackage("crd2pulumi", pkg, nil, nil, true, false)
5366
if err != nil {
@@ -58,19 +71,19 @@ func GenerateJava(pg *PackageGenerator, name string) (map[string]*bytes.Buffer,
5871
delete(pkg.Language, langName)
5972

6073
// Pin the kubernetes provider version used
61-
utilsPath := "src/main/java/com/pulumi/" + name + "/Utilities.java"
74+
utilsPath := "src/main/java/" + namespacePath + "/" + cs.PackageName + "/Utilities.java"
6275
utils, ok := files[utilsPath]
6376
if !ok {
64-
return nil, fmt.Errorf("cannot find generated utilities.ts")
77+
return nil, fmt.Errorf("cannot find generated Utilities.java at path: %s", utilsPath)
6578
}
6679
re := regexp.MustCompile(`static \{(?:[^{}]|{[^{}]*})*}`)
6780
files[utilsPath] = []byte(re.ReplaceAllString(string(utils), `static {
6881
version = "4.9.0";
6982
}`))
7083

7184
var unneededJavaFiles = []string{
72-
"src/main/java/com/pulumi/" + name + "/Provider.java",
73-
"src/main/java/com/pulumi/" + name + "/ProviderArgs.java",
85+
"src/main/java/" + namespacePath + "/" + cs.PackageName + "/Provider.java",
86+
"src/main/java/" + namespacePath + "/" + cs.PackageName + "/ProviderArgs.java",
7487
"src/main/java/com/pulumi/kubernetes/meta/v1/inputs/ObjectMetaArgs.java",
7588
"src/main/java/com/pulumi/kubernetes/meta/v1/outputs/ObjectMeta.java",
7689
}

pkg/codegen/language.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,13 @@ const Python string = "python"
3232
const Java string = "java"
3333

3434
type CodegenSettings struct {
35-
Language string
36-
OutputDir string
37-
PackageName string
38-
PackageVersion string
39-
Overwrite bool
40-
ShouldGenerate bool
35+
Language string
36+
OutputDir string
37+
PackageName string
38+
PackageNamespace string
39+
PackageVersion string
40+
Overwrite bool
41+
ShouldGenerate bool
4142
}
4243

4344
func (cs *CodegenSettings) Path() string {

pkg/codegen/nodejs.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,11 @@ export type ObjectMeta = k8s.types.input.meta.v1.ObjectMeta;
2929
export type ObjectMetaPatch = k8s.types.input.meta.v1.ObjectMetaPatch;
3030
`
3131

32-
func GenerateNodeJS(pg *PackageGenerator, name string) (map[string]*bytes.Buffer, error) {
32+
func GenerateNodeJS(pg *PackageGenerator, cs *CodegenSettings) (map[string]*bytes.Buffer, error) {
3333
pkg := pg.SchemaPackageWithObjectMetaType()
3434
oldName := pkg.Name
35-
pkg.Name = name
35+
pkg.Name = cs.PackageName
36+
pkg.Namespace = cs.PackageNamespace
3637

3738
files, err := nodejs.GeneratePackage(PulumiToolName, pkg, nil, nil, true, nil)
3839
if err != nil {

0 commit comments

Comments
 (0)